diff --git a/linux/src/stm32flash_serial/src/AUTHORS b/linux/src/stm32flash_serial/src/AUTHORS deleted file mode 100644 index d096f2205..000000000 --- a/linux/src/stm32flash_serial/src/AUTHORS +++ /dev/null @@ -1,19 +0,0 @@ -Authors ordered by first contribution. - -Geoffrey McRae -Bret Olmsted -Tormod Volden -Jakob Malm -Reuben Dowle -Matthias Kubisch -Paul Fertser -Daniel Strnad -Jérémie Rapin -Christian Pointner -Mats Erik Andersson -Alexey Borovik -Antonio Borneo -Armin van der Togt -Brian Silverman -Georg Hofmann -Luis Rodrigues diff --git a/linux/src/stm32flash_serial/src/Android.mk b/linux/src/stm32flash_serial/src/Android.mk deleted file mode 100644 index 7be3d0018..000000000 --- a/linux/src/stm32flash_serial/src/Android.mk +++ /dev/null @@ -1,20 +0,0 @@ -TOP_LOCAL_PATH := $(call my-dir) - -include $(call all-named-subdir-makefiles, parsers) - -LOCAL_PATH := $(TOP_LOCAL_PATH) - -include $(CLEAR_VARS) -LOCAL_MODULE := stm32flash -LOCAL_SRC_FILES := \ - dev_table.c \ - i2c.c \ - init.c \ - main.c \ - port.c \ - serial_common.c \ - serial_platform.c \ - stm32.c \ - utils.c -LOCAL_STATIC_LIBRARIES := libparsers -include $(BUILD_EXECUTABLE) diff --git a/linux/src/stm32flash_serial/src/HOWTO b/linux/src/stm32flash_serial/src/HOWTO deleted file mode 100644 index d8f32eb04..000000000 --- a/linux/src/stm32flash_serial/src/HOWTO +++ /dev/null @@ -1,35 +0,0 @@ -Add new interfaces: -===================================================================== -Current version 0.4 supports the following interfaces: -- UART Windows (either "COMn" and "\\.\COMn"); -- UART posix/Linux (e.g. "/dev/ttyUSB0"); -- I2C Linux through standard driver "i2c-dev" (e.g. "/dev/i2c-n"). - -Starting from version 0.4, the back-end of stm32flash is modular and -ready to be expanded to support new interfaces. -I'm planning adding SPI on Linux through standard driver "spidev". -You are invited to contribute with more interfaces. - -To add a new interface you need to add a new file, populate the struct -port_interface (check at the end of files i2c.c, serial_posix.c and -serial_w32.c) and provide the relative functions to operate on the -interface: open/close, read/write, get_cfg_str and the optional gpio. -The include the new drive in Makefile and register the new struct -port_interface in file port.c in struct port_interface *ports[]. - -There are several USB-I2C adapter in the market, each providing its -own libraries to communicate with the I2C bus. -Could be interesting to provide as back-end a bridge between stm32flash -and such libraries (I have no plan on this item). - - -Add new STM32 devices: -===================================================================== -Add a new line in file dev_table.c, in table devices[]. -The fields of the table are listed in stm32.h, struct stm32_dev. - - -Cross compile on Linux host for Windows target with MinGW: -===================================================================== -I'm using a 64 bit Arch Linux machines, and I usually run: - make CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar diff --git a/linux/src/stm32flash_serial/src/I2C.txt b/linux/src/stm32flash_serial/src/I2C.txt deleted file mode 100644 index 4c05ff62d..000000000 --- a/linux/src/stm32flash_serial/src/I2C.txt +++ /dev/null @@ -1,94 +0,0 @@ -About I2C back-end communication in stm32flash -========================================================================== - -Starting from version v0.4, beside the serial communication port, -stm32flash adds support for I2C port to talk with STM32 bootloader. - -The current I2C back-end supports only the API provided by Linux kernel -driver "i2c-dev", so only I2C controllers with Linux kernel driver can be -used. -In Linux source code, most of the drivers for I2C and SMBUS controllers -are in - ./drivers/i2c/busses/ -Only I2C is supported by STM32 bootloader, so check the section below -about SMBUS. -No I2C support for Windows is available in stm32flash v0.4. - -Thanks to the new modular back-end, stm32flash can be easily extended to -support new back-ends and API. Check HOWTO file in stm32flash source code -for details. - -In the market there are several USB-to-I2C dongles; most of them are not -supported by kernel drivers. Manufacturer provide proprietary userspace -libraries using not standardized API. -These API and dongles could be supported in feature versions. - -There are currently 3 versions of STM32 bootloader for I2C communications: -- v1.0 using I2C clock stretching synchronization between host and STM32; -- v1.1 superset of v1.0, adds non stretching commands; -- v1.2 superset of v1.1, adds CRC command and compatibility with i2cdetect. -Details in ST application note AN2606. -All the bootloaders above are tested and working with stm32flash. - - -SMBUS controllers -========================================================================== - -Almost 50% of the drivers in Linux source code folder - ./drivers/i2c/busses/ -are for controllers that "only" support SMBUS protocol. They can NOT -operate with STM32 bootloader. -To identify if your controller supports I2C, use command: - i2cdetect -F n -where "n" is the number of the I2C interface (e.g. n=3 for "/dev/i2c-3"). -Controllers that supports I2C will report - I2C yes -Controller that support both I2C and SMBUS are ok. - -If you are interested on details about SMBUS protocol, you can download -the current specs from - http://smbus.org/specs/smbus20.pdf -and you can read the files in Linux source code - ./Documentation/i2c/i2c-protocol - ./Documentation/i2c/smbus-protocol - - -About bootloader v1.0 -========================================================================== - -Version v1.0 can have issues with some I2C controllers due to use of clock -stretching during commands that require long operations, like flash erase -and programming. - -Clock stretching is a technique to synchronize host and I2C device. When -I2C device wants to force a delay in the communication, it push "low" the -I2C clock; the I2C controller detects it and waits until I2C clock returns -"high". -Most I2C controllers set a "timeout" for clock stretching, ranging from -few milli-seconds to seconds depending on specific HW or SW driver. - -It is possible that the timeout in your I2C controller is smaller than the -delay required for flash erase or programming. In this case the I2C -controller will timeout and report error to stm32flash. -There is no possibility for stm32flash to retry, so it can only signal the -error and exit. - -To by-pass the issue with bootloader v1.0 you can modify the kernel driver -of your I2C controller. Not an easy job, since every controller has its own -way to handle the timeout. - -In my case I'm using the I2C controller integrated in the VGA port of my -laptop HP EliteBook 8460p. I built the 0.25$ VGA-to-I2C adapter reported in - http://www.paintyourdragon.com/?p=43 -To change the timeout of the I2C controller I had to modify the kernel file - drivers/gpu/drm/radeon/radeon_i2c.c -line 969 -- i2c->bit.timeout = usecs_to_jiffies(2200); /* from VESA */ -+ i2c->bit.timeout = msecs_to_jiffies(5000); /* 5s for STM32 */ -and recompile it. -Then - $> modprobe i2c-dev - $> chmod 666 /dev/i2c-7 - #> stm32flash -a 0x39 /dev/i2c-7 - -2014-09-16 Antonio Borneo diff --git a/linux/src/stm32flash_serial/src/Makefile b/linux/src/stm32flash_serial/src/Makefile deleted file mode 100644 index 0328d5588..000000000 --- a/linux/src/stm32flash_serial/src/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -PREFIX = /usr/local -CFLAGS += -Wall -g - -INSTALL = install - -OBJS = dev_table.o \ - i2c.o \ - init.o \ - main.o \ - port.o \ - serial_common.o \ - serial_platform.o \ - stm32.o \ - utils.o - -LIBOBJS = parsers/parsers.a - -all: stm32flash - -serial_platform.o: serial_posix.c serial_w32.c - -parsers/parsers.a: - cd parsers && $(MAKE) parsers.a - -stm32flash: $(OBJS) $(LIBOBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBOBJS) - -clean: - rm -f $(OBJS) stm32flash - cd parsers && $(MAKE) $@ - -install: all - $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin - $(INSTALL) -m 755 stm32flash $(DESTDIR)$(PREFIX)/bin - $(INSTALL) -d $(DESTDIR)$(PREFIX)/share/man/man1 - $(INSTALL) -m 644 stm32flash.1 $(DESTDIR)$(PREFIX)/share/man/man1 - -.PHONY: all clean install diff --git a/linux/src/stm32flash_serial/src/TODO b/linux/src/stm32flash_serial/src/TODO deleted file mode 100644 index 41df614ff..000000000 --- a/linux/src/stm32flash_serial/src/TODO +++ /dev/null @@ -1,7 +0,0 @@ - -stm32: -- Add support for variable page size - -AUTHORS: -- Add contributors from Geoffrey's commits - diff --git a/linux/src/stm32flash_serial/src/dev_table.c b/linux/src/stm32flash_serial/src/dev_table.c deleted file mode 100644 index 399cd9d08..000000000 --- a/linux/src/stm32flash_serial/src/dev_table.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "stm32.h" - -/* - * Device table, corresponds to the "Bootloader device-dependant parameters" - * table in ST document AN2606. - * Note that the option bytes upper range is inclusive! - */ -const stm32_dev_t devices[] = { - /* F0 */ - {0x440, "STM32F051xx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, - {0x444, "STM32F030/F031" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, - {0x445, "STM32F042xx" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, - {0x448, "STM32F072xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, - /* F1 */ - {0x412, "Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x410, "Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x414, "High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x420, "Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x428, "High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x418, "Connectivity line" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, - {0x430, "XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, - /* Note that F2 and F4 devices have sectors of different page sizes - and only the first sectors (of one page size) are included here */ - /* F2 */ - {0x411, "STM32F2xx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, - /* F3 */ - {0x432, "STM32F373/8" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x422, "F302xB/303xB/358" , 0x20001400, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x439, "STM32F302x4(6/8)" , 0x20001800, 0x20004000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x438, "F303x4/334/328" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - /* F4 */ - {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, - /* 0x419 is also used for STM32F429/39 but with other bootloader ID... */ - {0x419, "STM32F427/37" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - /* L0 */ - {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - /* L1 */ - {0x416, "L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x429, "L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x427, "L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, - {0x436, "L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - {0x437, "L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - /* These are not (yet) in AN2606: */ - {0x641, "Medium_Density PL" , 0x20000200, 0x00005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, - {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 1, 2048, 0, 0, 0, 0}, - {0x0} -}; diff --git a/linux/src/stm32flash_serial/src/gpl-2.0.txt b/linux/src/stm32flash_serial/src/gpl-2.0.txt deleted file mode 100644 index d159169d1..000000000 --- a/linux/src/stm32flash_serial/src/gpl-2.0.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/linux/src/stm32flash_serial/src/i2c.c b/linux/src/stm32flash_serial/src/i2c.c deleted file mode 100644 index 10e6bb15a..000000000 --- a/linux/src/stm32flash_serial/src/i2c.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - - -#if !defined(__linux__) - -static port_err_t i2c_open(struct port_interface *port, - struct port_options *ops) -{ - return PORT_ERR_NODEV; -} - -struct port_interface port_i2c = { - .name = "i2c", - .open = i2c_open, -}; - -#else - -#ifdef __ANDROID__ -#define I2C_SLAVE 0x0703 /* Use this slave address */ -#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */ -/* To determine what functionality is present */ -#define I2C_FUNC_I2C 0x00000001 -#else -#include -#include -#endif - -#include - -struct i2c_priv { - int fd; - int addr; -}; - -static port_err_t i2c_open(struct port_interface *port, - struct port_options *ops) -{ - struct i2c_priv *h; - int fd, addr, ret; - unsigned long funcs; - - /* 1. check device name match */ - if (strncmp(ops->device, "/dev/i2c-", strlen("/dev/i2c-"))) - return PORT_ERR_NODEV; - - /* 2. check options */ - addr = ops->bus_addr; - if (addr < 0x03 || addr > 0x77) { - fprintf(stderr, "I2C address out of range [0x03-0x77]\n"); - return PORT_ERR_UNKNOWN; - } - - /* 3. open it */ - h = calloc(sizeof(*h), 1); - if (h == NULL) { - fprintf(stderr, "End of memory\n"); - return PORT_ERR_UNKNOWN; - } - fd = open(ops->device, O_RDWR); - if (fd < 0) { - fprintf(stderr, "Unable to open special file \"%s\"\n", - ops->device); - free(h); - return PORT_ERR_UNKNOWN; - } - - /* 3.5. Check capabilities */ - ret = ioctl(fd, I2C_FUNCS, &funcs); - if (ret < 0) { - fprintf(stderr, "I2C ioctl(funcs) error %d\n", errno); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - if ((funcs & I2C_FUNC_I2C) == 0) { - fprintf(stderr, "Error: controller is not I2C, only SMBUS.\n"); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - - /* 4. set options */ - ret = ioctl(fd, I2C_SLAVE, addr); - if (ret < 0) { - fprintf(stderr, "I2C ioctl(slave) error %d\n", errno); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - - h->fd = fd; - h->addr = addr; - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t i2c_close(struct port_interface *port) -{ - struct i2c_priv *h; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - close(h->fd); - free(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t i2c_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - struct i2c_priv *h; - int ret; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - ret = read(h->fd, buf, nbyte); - if (ret != nbyte) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; -} - -static port_err_t i2c_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - struct i2c_priv *h; - int ret; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - ret = write(h->fd, buf, nbyte); - if (ret != nbyte) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; -} - -static port_err_t i2c_gpio(struct port_interface *port, serial_gpio_t n, - int level) -{ - return PORT_ERR_OK; -} - -static const char *i2c_get_cfg_str(struct port_interface *port) -{ - struct i2c_priv *h; - static char str[11]; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return "INVALID"; - snprintf(str, sizeof(str), "addr 0x%2x", h->addr); - return str; -} - -static struct varlen_cmd i2c_cmd_get_reply[] = { - {0x10, 11}, - {0x11, 17}, - {0x12, 18}, - { /* sentinel */ } -}; - -struct port_interface port_i2c = { - .name = "i2c", - .flags = PORT_STRETCH_W, - .open = i2c_open, - .close = i2c_close, - .read = i2c_read, - .write = i2c_write, - .gpio = i2c_gpio, - .cmd_get_reply = i2c_cmd_get_reply, - .get_cfg_str = i2c_get_cfg_str, -}; - -#endif diff --git a/linux/src/stm32flash_serial/src/init.c b/linux/src/stm32flash_serial/src/init.c deleted file mode 100644 index 77a571bd8..000000000 --- a/linux/src/stm32flash_serial/src/init.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include "init.h" -#include "serial.h" -#include "stm32.h" -#include "port.h" - -struct gpio_list { - struct gpio_list *next; - int gpio; -}; - - -static int write_to(const char *filename, const char *value) -{ - int fd, ret; - - fd = open(filename, O_WRONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open file \"%s\"\n", filename); - return 0; - } - ret = write(fd, value, strlen(value)); - if (ret < 0) { - fprintf(stderr, "Error writing in file \"%s\"\n", filename); - close(fd); - return 0; - } - close(fd); - return 1; -} - -#if !defined(__linux__) -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) -{ - fprintf(stderr, "GPIO control only available in Linux\n"); - return 0; -} -#else -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) -{ - char num[16]; /* sized to carry MAX_INT */ - char file[48]; /* sized to carry longest filename */ - struct stat buf; - struct gpio_list *new; - int ret; - - sprintf(file, "/sys/class/gpio/gpio%d/direction", n); - ret = stat(file, &buf); - if (ret) { - /* file miss, GPIO not exported yet */ - sprintf(num, "%d", n); - ret = write_to("/sys/class/gpio/export", num); - if (!ret) - return 0; - ret = stat(file, &buf); - if (ret) { - fprintf(stderr, "GPIO %d not available\n", n); - return 0; - } - new = (struct gpio_list *)malloc(sizeof(struct gpio_list)); - if (new == NULL) { - fprintf(stderr, "Out of memory\n"); - return 0; - } - new->gpio = n; - new->next = *gpio_to_release; - *gpio_to_release = new; - } - - return write_to(file, level ? "high" : "low"); -} -#endif - -static int release_gpio(int n) -{ - char num[16]; /* sized to carry MAX_INT */ - - sprintf(num, "%d", n); - return write_to("/sys/class/gpio/unexport", num); -} - -static int gpio_sequence(struct port_interface *port, const char *s, size_t l) -{ - struct gpio_list *gpio_to_release = NULL, *to_free; - int ret, level, gpio; - - ret = 1; - while (ret == 1 && *s && l > 0) { - if (*s == '-') { - level = 0; - s++; - l--; - } else - level = 1; - - if (isdigit(*s)) { - gpio = atoi(s); - while (isdigit(*s)) { - s++; - l--; - } - } else if (!strncmp(s, "rts", 3)) { - gpio = -GPIO_RTS; - s += 3; - l -= 3; - } else if (!strncmp(s, "dtr", 3)) { - gpio = -GPIO_DTR; - s += 3; - l -= 3; - } else if (!strncmp(s, "brk", 3)) { - gpio = -GPIO_BRK; - s += 3; - l -= 3; - } else { - fprintf(stderr, "Character \'%c\' is not a digit\n", *s); - ret = 0; - break; - } - - if (*s && (l > 0)) { - if (*s == ',') { - s++; - l--; - } else { - fprintf(stderr, "Character \'%c\' is not a separator\n", *s); - ret = 0; - break; - } - } - if (gpio < 0) - ret = (port->gpio(port, -gpio, level) == PORT_ERR_OK); - else - ret = drive_gpio(gpio, level, &gpio_to_release); - usleep(100000); - } - - while (gpio_to_release) { - release_gpio(gpio_to_release->gpio); - to_free = gpio_to_release; - gpio_to_release = gpio_to_release->next; - free(to_free); - } - usleep(500000); - return ret; -} - -static int gpio_bl_entry(struct port_interface *port, const char *seq) -{ - char *s; - - if (seq == NULL || seq[0] == ':') - return 1; - - s = strchr(seq, ':'); - if (s == NULL) - return gpio_sequence(port, seq, strlen(seq)); - - return gpio_sequence(port, seq, s - seq); -} - -static int gpio_bl_exit(struct port_interface *port, const char *seq) -{ - char *s; - - if (seq == NULL) - return 1; - - s = strchr(seq, ':'); - if (s == NULL || s[1] == '\0') - return 1; - - return gpio_sequence(port, s + 1, strlen(s + 1)); -} - -int init_bl_entry(struct port_interface *port, const char *seq) -{ - if (seq) - return gpio_bl_entry(port, seq); - - return 1; -} - -int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq) -{ - if (seq) - return gpio_bl_exit(port, seq); - - if (stm32_reset_device(stm) != STM32_ERR_OK) - return 0; - return 1; -} diff --git a/linux/src/stm32flash_serial/src/init.h b/linux/src/stm32flash_serial/src/init.h deleted file mode 100644 index 6075b519b..000000000 --- a/linux/src/stm32flash_serial/src/init.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _INIT_H -#define _INIT_H - -#include "stm32.h" -#include "port.h" - -int init_bl_entry(struct port_interface *port, const char *seq); -int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq); - -#endif diff --git a/linux/src/stm32flash_serial/src/main.c b/linux/src/stm32flash_serial/src/main.c deleted file mode 100644 index f081d6131..000000000 --- a/linux/src/stm32flash_serial/src/main.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright 2010 Geoffrey McRae - Copyright 2011 Steve Markgraf - Copyright 2012 Tormod Volden - Copyright 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "init.h" -#include "utils.h" -#include "serial.h" -#include "stm32.h" -#include "parsers/parser.h" -#include "port.h" - -#include "parsers/binary.h" -#include "parsers/hex.h" - -#define VERSION "Arduino_STM32_0.9" - -/* device globals */ -stm32_t *stm = NULL; - -void *p_st = NULL; -parser_t *parser = NULL; - -/* settings */ -struct port_options port_opts = { - .device = NULL, - .baudRate = SERIAL_BAUD_57600, - .serial_mode = "8e1", - .bus_addr = 0, - .rx_frame_max = STM32_MAX_RX_FRAME, - .tx_frame_max = STM32_MAX_TX_FRAME, -}; -int rd = 0; -int wr = 0; -int wu = 0; -int rp = 0; -int ur = 0; -int eraseOnly = 0; -int crc = 0; -int npages = 0; -int spage = 0; -int no_erase = 0; -char verify = 0; -int retry = 10; -char exec_flag = 0; -uint32_t execute = 0; -char init_flag = 1; -char force_binary = 0; -char reset_flag = 0; -char *filename; -char *gpio_seq = NULL; -uint32_t start_addr = 0; -uint32_t readwrite_len = 0; - -/* functions */ -int parse_options(int argc, char *argv[]); -void show_help(char *name); - -static int is_addr_in_ram(uint32_t addr) -{ - return addr >= stm->dev->ram_start && addr < stm->dev->ram_end; -} - -static int is_addr_in_flash(uint32_t addr) -{ - return addr >= stm->dev->fl_start && addr < stm->dev->fl_end; -} - -static int flash_addr_to_page_floor(uint32_t addr) -{ - if (!is_addr_in_flash(addr)) - return 0; - - return (addr - stm->dev->fl_start) / stm->dev->fl_ps; -} - -static int flash_addr_to_page_ceil(uint32_t addr) -{ - if (!(addr >= stm->dev->fl_start && addr <= stm->dev->fl_end)) - return 0; - - return (addr + stm->dev->fl_ps - 1 - stm->dev->fl_start) - / stm->dev->fl_ps; -} - -static uint32_t flash_page_to_addr(int page) -{ - return stm->dev->fl_start + page * stm->dev->fl_ps; -} - -int main(int argc, char* argv[]) { - struct port_interface *port = NULL; - int ret = 1; - stm32_err_t s_err; - parser_err_t perr; - FILE *diag = stdout; - - fprintf(diag, "stm32flash " VERSION "\n\n"); - fprintf(diag, "http://github.com/rogerclarkmelbourne/arduino_stm32\n\n"); - if (parse_options(argc, argv) != 0) - goto close; - - if (rd && filename[0] == '-') { - diag = stderr; - } - - if (wr) { - /* first try hex */ - if (!force_binary) { - parser = &PARSER_HEX; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - } - - if (force_binary || (perr = parser->open(p_st, filename, 0)) != PARSER_ERR_OK) { - if (force_binary || perr == PARSER_ERR_INVALID_FILE) { - if (!force_binary) { - parser->close(p_st); - p_st = NULL; - } - - /* now try binary */ - parser = &PARSER_BINARY; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - perr = parser->open(p_st, filename, 0); - } - - /* if still have an error, fail */ - if (perr != PARSER_ERR_OK) { - fprintf(stderr, "%s ERROR: %s\n", parser->name, parser_errstr(perr)); - if (perr == PARSER_ERR_SYSTEM) perror(filename); - goto close; - } - } - - fprintf(diag, "Using Parser : %s\n", parser->name); - } else { - parser = &PARSER_BINARY; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - } - - if (port_open(&port_opts, &port) != PORT_ERR_OK) { - fprintf(stderr, "Failed to open port: %s\n", port_opts.device); - goto close; - } - - fprintf(diag, "Interface %s: %s\n", port->name, port->get_cfg_str(port)); - if (init_flag && init_bl_entry(port, gpio_seq) == 0) - goto close; - stm = stm32_init(port, init_flag); - if (!stm) - goto close; - - fprintf(diag, "Version : 0x%02x\n", stm->bl_version); - if (port->flags & PORT_GVR_ETX) { - fprintf(diag, "Option 1 : 0x%02x\n", stm->option1); - fprintf(diag, "Option 2 : 0x%02x\n", stm->option2); - } - fprintf(diag, "Device ID : 0x%04x (%s)\n", stm->pid, stm->dev->name); - fprintf(diag, "- RAM : %dKiB (%db reserved by bootloader)\n", (stm->dev->ram_end - 0x20000000) / 1024, stm->dev->ram_start - 0x20000000); - fprintf(diag, "- Flash : %dKiB (sector size: %dx%d)\n", (stm->dev->fl_end - stm->dev->fl_start ) / 1024, stm->dev->fl_pps, stm->dev->fl_ps); - fprintf(diag, "- Option RAM : %db\n", stm->dev->opt_end - stm->dev->opt_start + 1); - fprintf(diag, "- System RAM : %dKiB\n", (stm->dev->mem_end - stm->dev->mem_start) / 1024); - - uint8_t buffer[256]; - uint32_t addr, start, end; - unsigned int len; - int failed = 0; - int first_page, num_pages; - - /* - * Cleanup addresses: - * - * Starting from options - * start_addr, readwrite_len, spage, npages - * and using device memory size, compute - * start, end, first_page, num_pages - */ - if (start_addr || readwrite_len) { - start = start_addr; - - if (is_addr_in_flash(start)) - end = stm->dev->fl_end; - else { - no_erase = 1; - if (is_addr_in_ram(start)) - end = stm->dev->ram_end; - else - end = start + sizeof(uint32_t); - } - - if (readwrite_len && (end > start + readwrite_len)) - end = start + readwrite_len; - - first_page = flash_addr_to_page_floor(start); - if (!first_page && end == stm->dev->fl_end) - num_pages = 0xff; /* mass erase */ - else - num_pages = flash_addr_to_page_ceil(end) - first_page; - } else if (!spage && !npages) { - start = stm->dev->fl_start; - end = stm->dev->fl_end; - first_page = 0; - num_pages = 0xff; /* mass erase */ - } else { - first_page = spage; - start = flash_page_to_addr(first_page); - if (start > stm->dev->fl_end) { - fprintf(stderr, "Address range exceeds flash size.\n"); - goto close; - } - - if (npages) { - num_pages = npages; - end = flash_page_to_addr(first_page + num_pages); - if (end > stm->dev->fl_end) - end = stm->dev->fl_end; - } else { - end = stm->dev->fl_end; - num_pages = flash_addr_to_page_ceil(end) - first_page; - } - - if (!first_page && end == stm->dev->fl_end) - num_pages = 0xff; /* mass erase */ - } - - if (rd) { - unsigned int max_len = port_opts.rx_frame_max; - - fprintf(diag, "Memory read\n"); - - perr = parser->open(p_st, filename, 1); - if (perr != PARSER_ERR_OK) { - fprintf(stderr, "%s ERROR: %s\n", parser->name, parser_errstr(perr)); - if (perr == PARSER_ERR_SYSTEM) - perror(filename); - goto close; - } - - fflush(diag); - addr = start; - while(addr < end) { - uint32_t left = end - addr; - len = max_len > left ? left : max_len; - s_err = stm32_read_memory(stm, addr, buffer, len); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read memory at address 0x%08x, target write-protected?\n", addr); - goto close; - } - if (parser->write(p_st, buffer, len) != PARSER_ERR_OK) - { - fprintf(stderr, "Failed to write data to file\n"); - goto close; - } - addr += len; - - fprintf(diag, - "\rRead address 0x%08x (%.2f%%) ", - addr, - (100.0f / (float)(end - start)) * (float)(addr - start) - ); - fflush(diag); - } - fprintf(diag, "Done.\n"); - ret = 0; - goto close; - } else if (rp) { - fprintf(stdout, "Read-Protecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_readprot_memory(stm); - fprintf(stdout, "Done.\n"); - } else if (ur) { - fprintf(stdout, "Read-UnProtecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_runprot_memory(stm); - fprintf(stdout, "Done.\n"); - } else if (eraseOnly) { - ret = 0; - fprintf(stdout, "Erasing flash\n"); - - if (num_pages != 0xff && - (start != flash_page_to_addr(first_page) - || end != flash_page_to_addr(first_page + num_pages))) { - fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); - ret = 1; - goto close; - } - - s_err = stm32_erase_memory(stm, first_page, num_pages); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to erase memory\n"); - ret = 1; - goto close; - } - } else if (wu) { - fprintf(diag, "Write-unprotecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_wunprot_memory(stm); - fprintf(diag, "Done.\n"); - - } else if (wr) { - fprintf(diag, "Write to memory\n"); - - off_t offset = 0; - ssize_t r; - unsigned int size; - unsigned int max_wlen, max_rlen; - - max_wlen = port_opts.tx_frame_max - 2; /* skip len and crc */ - max_wlen &= ~3; /* 32 bit aligned */ - - max_rlen = port_opts.rx_frame_max; - max_rlen = max_rlen < max_wlen ? max_rlen : max_wlen; - - /* Assume data from stdin is whole device */ - if (filename[0] == '-' && filename[1] == '\0') - size = end - start; - else - size = parser->size(p_st); - - // TODO: It is possible to write to non-page boundaries, by reading out flash - // from partial pages and combining with the input data - // if ((start % stm->dev->fl_ps) != 0 || (end % stm->dev->fl_ps) != 0) { - // fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); - // goto close; - // } - - // TODO: If writes are not page aligned, we should probably read out existing flash - // contents first, so it can be preserved and combined with new data - if (!no_erase && num_pages) { - fprintf(diag, "Erasing memory\n"); - s_err = stm32_erase_memory(stm, first_page, num_pages); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to erase memory\n"); - goto close; - } - } - - fflush(diag); - addr = start; - while(addr < end && offset < size) { - uint32_t left = end - addr; - len = max_wlen > left ? left : max_wlen; - len = len > size - offset ? size - offset : len; - - if (parser->read(p_st, buffer, &len) != PARSER_ERR_OK) - goto close; - - if (len == 0) { - if (filename[0] == '-') { - break; - } else { - fprintf(stderr, "Failed to read input file\n"); - goto close; - } - } - - again: - s_err = stm32_write_memory(stm, addr, buffer, len); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to write memory at address 0x%08x\n", addr); - goto close; - } - - if (verify) { - uint8_t compare[len]; - unsigned int offset, rlen; - - offset = 0; - while (offset < len) { - rlen = len - offset; - rlen = rlen < max_rlen ? rlen : max_rlen; - s_err = stm32_read_memory(stm, addr + offset, compare + offset, rlen); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read memory at address 0x%08x\n", addr + offset); - goto close; - } - offset += rlen; - } - - for(r = 0; r < len; ++r) - if (buffer[r] != compare[r]) { - if (failed == retry) { - fprintf(stderr, "Failed to verify at address 0x%08x, expected 0x%02x and found 0x%02x\n", - (uint32_t)(addr + r), - buffer [r], - compare[r] - ); - goto close; - } - ++failed; - goto again; - } - - failed = 0; - } - - addr += len; - offset += len; - - fprintf(diag, - "\rWrote %saddress 0x%08x (%.2f%%) ", - verify ? "and verified " : "", - addr, - (100.0f / size) * offset - ); - fflush(diag); - - } - - fprintf(diag, "Done.\n"); - ret = 0; - goto close; - } else if (crc) { - uint32_t crc_val = 0; - - fprintf(diag, "CRC computation\n"); - - s_err = stm32_crc_wrapper(stm, start, end - start, &crc_val); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read CRC\n"); - goto close; - } - fprintf(diag, "CRC(0x%08x-0x%08x) = 0x%08x\n", start, end, - crc_val); - ret = 0; - goto close; - } else - ret = 0; - -close: - if (stm && exec_flag && ret == 0) { - if (execute == 0) - execute = stm->dev->fl_start; - - fprintf(diag, "\nStarting execution at address 0x%08x... ", execute); - fflush(diag); - if (stm32_go(stm, execute) == STM32_ERR_OK) { - reset_flag = 0; - fprintf(diag, "done.\n"); - } else - fprintf(diag, "failed.\n"); - } - - if (stm && reset_flag) { - fprintf(diag, "\nResetting device... "); - fflush(diag); - if (init_bl_exit(stm, port, gpio_seq)) - fprintf(diag, "done.\n"); - else fprintf(diag, "failed.\n"); - } - - if (p_st ) parser->close(p_st); - if (stm ) stm32_close (stm); - if (port) - port->close(port); - - fprintf(diag, "\n"); - return ret; -} - -int parse_options(int argc, char *argv[]) -{ - int c; - char *pLen; - - while ((c = getopt(argc, argv, "a:b:m:r:w:e:vn:g:jkfcChuos:S:F:i:R")) != -1) { - switch(c) { - case 'a': - port_opts.bus_addr = strtoul(optarg, NULL, 0); - break; - - case 'b': - port_opts.baudRate = serial_get_baud(strtoul(optarg, NULL, 0)); - if (port_opts.baudRate == SERIAL_BAUD_INVALID) { - serial_baud_t baudrate; - fprintf(stderr, "Invalid baud rate, valid options are:\n"); - for (baudrate = SERIAL_BAUD_1200; baudrate != SERIAL_BAUD_INVALID; ++baudrate) - fprintf(stderr, " %d\n", serial_get_baud_int(baudrate)); - return 1; - } - break; - - case 'm': - if (strlen(optarg) != 3 - || serial_get_bits(optarg) == SERIAL_BITS_INVALID - || serial_get_parity(optarg) == SERIAL_PARITY_INVALID - || serial_get_stopbit(optarg) == SERIAL_STOPBIT_INVALID) { - fprintf(stderr, "Invalid serial mode\n"); - return 1; - } - port_opts.serial_mode = optarg; - break; - - case 'r': - case 'w': - rd = rd || c == 'r'; - wr = wr || c == 'w'; - if (rd && wr) { - fprintf(stderr, "ERROR: Invalid options, can't read & write at the same time\n"); - return 1; - } - filename = optarg; - if (filename[0] == '-') { - force_binary = 1; - } - break; - case 'e': - if (readwrite_len || start_addr) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } - npages = strtoul(optarg, NULL, 0); - if (npages > 0xFF || npages < 0) { - fprintf(stderr, "ERROR: You need to specify a page count between 0 and 255"); - return 1; - } - if (!npages) - no_erase = 1; - break; - case 'u': - wu = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't write unprotect and read/write at the same time\n"); - return 1; - } - break; - - case 'j': - rp = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't read protect and read/write at the same time\n"); - return 1; - } - break; - - case 'k': - ur = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't read unprotect and read/write at the same time\n"); - return 1; - } - break; - - case 'o': - eraseOnly = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't erase-only and read/write at the same time\n"); - return 1; - } - break; - - case 'v': - verify = 1; - break; - - case 'n': - retry = strtoul(optarg, NULL, 0); - break; - - case 'g': - exec_flag = 1; - execute = strtoul(optarg, NULL, 0); - if (execute % 4 != 0) { - fprintf(stderr, "ERROR: Execution address must be word-aligned\n"); - return 1; - } - break; - case 's': - if (readwrite_len || start_addr) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } - spage = strtoul(optarg, NULL, 0); - break; - case 'S': - if (spage || npages) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } else { - start_addr = strtoul(optarg, &pLen, 0); - if (*pLen == ':') { - pLen++; - readwrite_len = strtoul(pLen, NULL, 0); - if (readwrite_len == 0) { - fprintf(stderr, "ERROR: Invalid options, can't specify zero length\n"); - return 1; - } - } - } - break; - case 'F': - port_opts.rx_frame_max = strtoul(optarg, &pLen, 0); - if (*pLen == ':') { - pLen++; - port_opts.tx_frame_max = strtoul(pLen, NULL, 0); - } - if (port_opts.rx_frame_max < 0 - || port_opts.tx_frame_max < 0) { - fprintf(stderr, "ERROR: Invalid negative value for option -F\n"); - return 1; - } - if (port_opts.rx_frame_max == 0) - port_opts.rx_frame_max = STM32_MAX_RX_FRAME; - if (port_opts.tx_frame_max == 0) - port_opts.tx_frame_max = STM32_MAX_TX_FRAME; - if (port_opts.rx_frame_max < 20 - || port_opts.tx_frame_max < 5) { - fprintf(stderr, "ERROR: current code cannot work with small frames.\n"); - fprintf(stderr, "min(RX) = 20, min(TX) = 5\n"); - return 1; - } - if (port_opts.rx_frame_max > STM32_MAX_RX_FRAME) { - fprintf(stderr, "WARNING: Ignore RX length in option -F\n"); - port_opts.rx_frame_max = STM32_MAX_RX_FRAME; - } - if (port_opts.tx_frame_max > STM32_MAX_TX_FRAME) { - fprintf(stderr, "WARNING: Ignore TX length in option -F\n"); - port_opts.tx_frame_max = STM32_MAX_TX_FRAME; - } - break; - case 'f': - force_binary = 1; - break; - - case 'c': - init_flag = 0; - break; - - case 'h': - show_help(argv[0]); - exit(0); - - case 'i': - gpio_seq = optarg; - break; - - case 'R': - reset_flag = 1; - break; - - case 'C': - crc = 1; - break; - } - } - - for (c = optind; c < argc; ++c) { - if (port_opts.device) { - fprintf(stderr, "ERROR: Invalid parameter specified\n"); - show_help(argv[0]); - return 1; - } - port_opts.device = argv[c]; - } - - if (port_opts.device == NULL) { - fprintf(stderr, "ERROR: Device not specified\n"); - show_help(argv[0]); - return 1; - } - - if (!wr && verify) { - fprintf(stderr, "ERROR: Invalid usage, -v is only valid when writing\n"); - show_help(argv[0]); - return 1; - } - - return 0; -} - -void show_help(char *name) { - fprintf(stderr, - "Usage: %s [-bvngfhc] [-[rw] filename] [tty_device | i2c_device]\n" - " -a bus_address Bus address (e.g. for I2C port)\n" - " -b rate Baud rate (default 57600)\n" - " -m mode Serial port mode (default 8e1)\n" - " -r filename Read flash to file (or - stdout)\n" - " -w filename Write flash from file (or - stdout)\n" - " -C Compute CRC of flash content\n" - " -u Disable the flash write-protection\n" - " -j Enable the flash read-protection\n" - " -k Disable the flash read-protection\n" - " -o Erase only\n" - " -e n Only erase n pages before writing the flash\n" - " -v Verify writes\n" - " -n count Retry failed writes up to count times (default 10)\n" - " -g address Start execution at specified address (0 = flash start)\n" - " -S address[:length] Specify start address and optionally length for\n" - " read/write/erase operations\n" - " -F RX_length[:TX_length] Specify the max length of RX and TX frame\n" - " -s start_page Flash at specified page (0 = flash start)\n" - " -f Force binary parser\n" - " -h Show this help\n" - " -c Resume the connection (don't send initial INIT)\n" - " *Baud rate must be kept the same as the first init*\n" - " This is useful if the reset fails\n" - " -i GPIO_string GPIO sequence to enter/exit bootloader mode\n" - " GPIO_string=[entry_seq][:[exit_seq]]\n" - " sequence=[-]n[,sequence]\n" - " -R Reset device at exit.\n" - "\n" - "Examples:\n" - " Get device information:\n" - " %s /dev/ttyS0\n" - " or:\n" - " %s /dev/i2c-0\n" - "\n" - " Write with verify and then start execution:\n" - " %s -w filename -v -g 0x0 /dev/ttyS0\n" - "\n" - " Read flash to file:\n" - " %s -r filename /dev/ttyS0\n" - "\n" - " Read 100 bytes of flash from 0x1000 to stdout:\n" - " %s -r - -S 0x1000:100 /dev/ttyS0\n" - "\n" - " Start execution:\n" - " %s -g 0x0 /dev/ttyS0\n" - "\n" - " GPIO sequence:\n" - " - entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high\n" - " - exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high\n" - " %s -i -3,-2,2:3,-2,2 /dev/ttyS0\n", - name, - name, - name, - name, - name, - name, - name, - name - ); -} - diff --git a/linux/src/stm32flash_serial/src/parsers/Android.mk b/linux/src/stm32flash_serial/src/parsers/Android.mk deleted file mode 100644 index afec18cd5..000000000 --- a/linux/src/stm32flash_serial/src/parsers/Android.mk +++ /dev/null @@ -1,6 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := libparsers -LOCAL_SRC_FILES := binary.c hex.c -include $(BUILD_STATIC_LIBRARY) diff --git a/linux/src/stm32flash_serial/src/parsers/Makefile b/linux/src/stm32flash_serial/src/parsers/Makefile deleted file mode 100644 index bb7df1e02..000000000 --- a/linux/src/stm32flash_serial/src/parsers/Makefile +++ /dev/null @@ -1,12 +0,0 @@ - -CFLAGS += -Wall -g - -all: parsers.a - -parsers.a: binary.o hex.o - $(AR) rc $@ binary.o hex.o - -clean: - rm -f *.o parsers.a - -.PHONY: all clean diff --git a/linux/src/stm32flash_serial/src/parsers/binary.c b/linux/src/stm32flash_serial/src/parsers/binary.c deleted file mode 100644 index f491952bb..000000000 --- a/linux/src/stm32flash_serial/src/parsers/binary.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include - -#include "binary.h" - -typedef struct { - int fd; - char write; - struct stat stat; -} binary_t; - -void* binary_init() { - return calloc(sizeof(binary_t), 1); -} - -parser_err_t binary_open(void *storage, const char *filename, const char write) { - binary_t *st = storage; - if (write) { - if (filename[0] == '-') - st->fd = 1; - else - st->fd = open( - filename, -#ifndef __WIN32__ - O_WRONLY | O_CREAT | O_TRUNC, -#else - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, -#endif -#ifndef __WIN32__ - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH -#else - 0 -#endif - ); - st->stat.st_size = 0; - } else { - if (filename[0] == '-') { - st->fd = 0; - } else { - if (stat(filename, &st->stat) != 0) - return PARSER_ERR_INVALID_FILE; - st->fd = open(filename, -#ifndef __WIN32__ - O_RDONLY -#else - O_RDONLY | O_BINARY -#endif - ); - } - } - - st->write = write; - return st->fd == -1 ? PARSER_ERR_SYSTEM : PARSER_ERR_OK; -} - -parser_err_t binary_close(void *storage) { - binary_t *st = storage; - - if (st->fd) close(st->fd); - free(st); - return PARSER_ERR_OK; -} - -unsigned int binary_size(void *storage) { - binary_t *st = storage; - return st->stat.st_size; -} - -parser_err_t binary_read(void *storage, void *data, unsigned int *len) { - binary_t *st = storage; - unsigned int left = *len; - if (st->write) return PARSER_ERR_WRONLY; - - ssize_t r; - while(left > 0) { - r = read(st->fd, data, left); - /* If there is no data to read at all, return OK, but with zero read */ - if (r == 0 && left == *len) { - *len = 0; - return PARSER_ERR_OK; - } - if (r <= 0) return PARSER_ERR_SYSTEM; - left -= r; - data += r; - } - - *len = *len - left; - return PARSER_ERR_OK; -} - -parser_err_t binary_write(void *storage, void *data, unsigned int len) { - binary_t *st = storage; - if (!st->write) return PARSER_ERR_RDONLY; - - ssize_t r; - while(len > 0) { - r = write(st->fd, data, len); - if (r < 1) return PARSER_ERR_SYSTEM; - st->stat.st_size += r; - - len -= r; - data += r; - } - - return PARSER_ERR_OK; -} - -parser_t PARSER_BINARY = { - "Raw BINARY", - binary_init, - binary_open, - binary_close, - binary_size, - binary_read, - binary_write -}; - diff --git a/linux/src/stm32flash_serial/src/parsers/binary.h b/linux/src/stm32flash_serial/src/parsers/binary.h deleted file mode 100644 index d989acfa0..000000000 --- a/linux/src/stm32flash_serial/src/parsers/binary.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _PARSER_BINARY_H -#define _PARSER_BINARY_H - -#include "parser.h" - -extern parser_t PARSER_BINARY; -#endif diff --git a/linux/src/stm32flash_serial/src/parsers/hex.c b/linux/src/stm32flash_serial/src/parsers/hex.c deleted file mode 100644 index 3baf85623..000000000 --- a/linux/src/stm32flash_serial/src/parsers/hex.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include - -#include "hex.h" -#include "../utils.h" - -typedef struct { - size_t data_len, offset; - uint8_t *data; - uint8_t base; -} hex_t; - -void* hex_init() { - return calloc(sizeof(hex_t), 1); -} - -parser_err_t hex_open(void *storage, const char *filename, const char write) { - hex_t *st = storage; - if (write) { - return PARSER_ERR_RDONLY; - } else { - char mark; - int i, fd; - uint8_t checksum; - unsigned int c; - uint32_t base = 0; - unsigned int last_address = 0x0; - - fd = open(filename, O_RDONLY); - if (fd < 0) - return PARSER_ERR_SYSTEM; - - /* read in the file */ - - while(read(fd, &mark, 1) != 0) { - if (mark == '\n' || mark == '\r') continue; - if (mark != ':') - return PARSER_ERR_INVALID_FILE; - - char buffer[9]; - unsigned int reclen, address, type; - uint8_t *record = NULL; - - /* get the reclen, address, and type */ - buffer[8] = 0; - if (read(fd, &buffer, 8) != 8) return PARSER_ERR_INVALID_FILE; - if (sscanf(buffer, "%2x%4x%2x", &reclen, &address, &type) != 3) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* setup the checksum */ - checksum = - reclen + - ((address & 0xFF00) >> 8) + - ((address & 0x00FF) >> 0) + - type; - - switch(type) { - /* data record */ - case 0: - c = address - last_address; - st->data = realloc(st->data, st->data_len + c + reclen); - - /* if there is a gap, set it to 0xff and increment the length */ - if (c > 0) { - memset(&st->data[st->data_len], 0xff, c); - st->data_len += c; - } - - last_address = address + reclen; - record = &st->data[st->data_len]; - st->data_len += reclen; - break; - - /* extended segment address record */ - case 2: - base = 0; - break; - - /* extended linear address record */ - case 4: - base = address; - break; - } - - buffer[2] = 0; - for(i = 0; i < reclen; ++i) { - if (read(fd, &buffer, 2) != 2 || sscanf(buffer, "%2x", &c) != 1) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* add the byte to the checksum */ - checksum += c; - - switch(type) { - case 0: - if (record != NULL) { - record[i] = c; - } else { - return PARSER_ERR_INVALID_FILE; - } - break; - - case 2: - case 4: - base = (base << 8) | c; - break; - } - } - - /* read, scan, and verify the checksum */ - if ( - read(fd, &buffer, 2 ) != 2 || - sscanf(buffer, "%2x", &c) != 1 || - (uint8_t)(checksum + c) != 0x00 - ) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - switch(type) { - /* EOF */ - case 1: - close(fd); - return PARSER_ERR_OK; - - /* address record */ - case 2: base = base << 4; - case 4: base = be_u32(base); - /* Reset last_address since our base changed */ - last_address = 0; - - if (st->base == 0) { - st->base = base; - break; - } - - /* we cant cope with files out of order */ - if (base < st->base) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* if there is a gap, enlarge and fill with zeros */ - unsigned int len = base - st->base; - if (len > st->data_len) { - st->data = realloc(st->data, len); - memset(&st->data[st->data_len], 0, len - st->data_len); - st->data_len = len; - } - break; - } - } - - close(fd); - return PARSER_ERR_OK; - } -} - -parser_err_t hex_close(void *storage) { - hex_t *st = storage; - if (st) free(st->data); - free(st); - return PARSER_ERR_OK; -} - -unsigned int hex_size(void *storage) { - hex_t *st = storage; - return st->data_len; -} - -parser_err_t hex_read(void *storage, void *data, unsigned int *len) { - hex_t *st = storage; - unsigned int left = st->data_len - st->offset; - unsigned int get = left > *len ? *len : left; - - memcpy(data, &st->data[st->offset], get); - st->offset += get; - - *len = get; - return PARSER_ERR_OK; -} - -parser_err_t hex_write(void *storage, void *data, unsigned int len) { - return PARSER_ERR_RDONLY; -} - -parser_t PARSER_HEX = { - "Intel HEX", - hex_init, - hex_open, - hex_close, - hex_size, - hex_read, - hex_write -}; - diff --git a/linux/src/stm32flash_serial/src/parsers/hex.h b/linux/src/stm32flash_serial/src/parsers/hex.h deleted file mode 100644 index 02413c9c9..000000000 --- a/linux/src/stm32flash_serial/src/parsers/hex.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _PARSER_HEX_H -#define _PARSER_HEX_H - -#include "parser.h" - -extern parser_t PARSER_HEX; -#endif diff --git a/linux/src/stm32flash_serial/src/parsers/parser.h b/linux/src/stm32flash_serial/src/parsers/parser.h deleted file mode 100644 index c2fae3cf8..000000000 --- a/linux/src/stm32flash_serial/src/parsers/parser.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_PARSER -#define _H_PARSER - -enum parser_err { - PARSER_ERR_OK, - PARSER_ERR_SYSTEM, - PARSER_ERR_INVALID_FILE, - PARSER_ERR_WRONLY, - PARSER_ERR_RDONLY -}; -typedef enum parser_err parser_err_t; - -struct parser { - const char *name; - void* (*init )(); /* initialise the parser */ - parser_err_t (*open )(void *storage, const char *filename, const char write); /* open the file for read|write */ - parser_err_t (*close)(void *storage); /* close and free the parser */ - unsigned int (*size )(void *storage); /* get the total data size */ - parser_err_t (*read )(void *storage, void *data, unsigned int *len); /* read a block of data */ - parser_err_t (*write)(void *storage, void *data, unsigned int len); /* write a block of data */ -}; -typedef struct parser parser_t; - -static inline const char* parser_errstr(parser_err_t err) { - switch(err) { - case PARSER_ERR_OK : return "OK"; - case PARSER_ERR_SYSTEM : return "System Error"; - case PARSER_ERR_INVALID_FILE: return "Invalid File"; - case PARSER_ERR_WRONLY : return "Parser can only write"; - case PARSER_ERR_RDONLY : return "Parser can only read"; - default: - return "Unknown Error"; - } -} - -#endif diff --git a/linux/src/stm32flash_serial/src/port.c b/linux/src/stm32flash_serial/src/port.c deleted file mode 100644 index 08e58cc34..000000000 --- a/linux/src/stm32flash_serial/src/port.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include "serial.h" -#include "port.h" - - -extern struct port_interface port_serial; -extern struct port_interface port_i2c; - -static struct port_interface *ports[] = { - &port_serial, - &port_i2c, - NULL, -}; - - -port_err_t port_open(struct port_options *ops, struct port_interface **outport) -{ - int ret; - static struct port_interface **port; - - for (port = ports; *port; port++) { - ret = (*port)->open(*port, ops); - if (ret == PORT_ERR_NODEV) - continue; - if (ret == PORT_ERR_OK) - break; - fprintf(stderr, "Error probing interface \"%s\"\n", - (*port)->name); - } - if (*port == NULL) { - fprintf(stderr, "Cannot handle device \"%s\"\n", - ops->device); - return PORT_ERR_UNKNOWN; - } - - *outport = *port; - return PORT_ERR_OK; -} diff --git a/linux/src/stm32flash_serial/src/port.h b/linux/src/stm32flash_serial/src/port.h deleted file mode 100644 index 290f03496..000000000 --- a/linux/src/stm32flash_serial/src/port.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_PORT -#define _H_PORT - -typedef enum { - PORT_ERR_OK = 0, - PORT_ERR_NODEV, /* No such device */ - PORT_ERR_TIMEDOUT, /* Operation timed out */ - PORT_ERR_UNKNOWN, -} port_err_t; - -/* flags */ -#define PORT_BYTE (1 << 0) /* byte (not frame) oriented */ -#define PORT_GVR_ETX (1 << 1) /* cmd GVR returns protection status */ -#define PORT_CMD_INIT (1 << 2) /* use INIT cmd to autodetect speed */ -#define PORT_RETRY (1 << 3) /* allowed read() retry after timeout */ -#define PORT_STRETCH_W (1 << 4) /* warning for no-stretching commands */ - -/* all options and flags used to open and configure an interface */ -struct port_options { - const char *device; - serial_baud_t baudRate; - const char *serial_mode; - int bus_addr; - int rx_frame_max; - int tx_frame_max; -}; - -/* - * Specify the length of reply for command GET - * This is helpful for frame-oriented protocols, e.g. i2c, to avoid time - * consuming try-fail-timeout-retry operation. - * On byte-oriented protocols, i.e. UART, this information would be skipped - * after read the first byte, so not needed. - */ -struct varlen_cmd { - uint8_t version; - uint8_t length; -}; - -struct port_interface { - const char *name; - unsigned flags; - port_err_t (*open)(struct port_interface *port, struct port_options *ops); - port_err_t (*close)(struct port_interface *port); - port_err_t (*read)(struct port_interface *port, void *buf, size_t nbyte); - port_err_t (*write)(struct port_interface *port, void *buf, size_t nbyte); - port_err_t (*gpio)(struct port_interface *port, serial_gpio_t n, int level); - const char *(*get_cfg_str)(struct port_interface *port); - struct varlen_cmd *cmd_get_reply; - void *private; -}; - -port_err_t port_open(struct port_options *ops, struct port_interface **outport); - -#endif diff --git a/linux/src/stm32flash_serial/src/protocol.txt b/linux/src/stm32flash_serial/src/protocol.txt deleted file mode 100644 index 039109908..000000000 --- a/linux/src/stm32flash_serial/src/protocol.txt +++ /dev/null @@ -1,19 +0,0 @@ -The communication protocol used by ST bootloader is documented in following ST -application notes, depending on communication port. - -In current version of stm32flash are supported only UART and I2C ports. - -* AN3154: CAN protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/CD00264321.pdf - -* AN3155: USART protocol used in the STM32(TM) bootloader - http://www.st.com/web/en/resource/technical/document/application_note/CD00264342.pdf - -* AN4221: I2C protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/DM00072315.pdf - -* AN4286: SPI protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/DM00081379.pdf - -Boot mode selection for STM32 is documented in ST application note AN2606, available in ST website: - http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf diff --git a/linux/src/stm32flash_serial/src/serial.h b/linux/src/stm32flash_serial/src/serial.h deleted file mode 100644 index 227ba163b..000000000 --- a/linux/src/stm32flash_serial/src/serial.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _SERIAL_H -#define _SERIAL_H - -typedef struct serial serial_t; - -typedef enum { - SERIAL_PARITY_NONE, - SERIAL_PARITY_EVEN, - SERIAL_PARITY_ODD, - - SERIAL_PARITY_INVALID -} serial_parity_t; - -typedef enum { - SERIAL_BITS_5, - SERIAL_BITS_6, - SERIAL_BITS_7, - SERIAL_BITS_8, - - SERIAL_BITS_INVALID -} serial_bits_t; - -typedef enum { - SERIAL_BAUD_1200, - SERIAL_BAUD_1800, - SERIAL_BAUD_2400, - SERIAL_BAUD_4800, - SERIAL_BAUD_9600, - SERIAL_BAUD_19200, - SERIAL_BAUD_38400, - SERIAL_BAUD_57600, - SERIAL_BAUD_115200, - SERIAL_BAUD_128000, - SERIAL_BAUD_230400, - SERIAL_BAUD_256000, - SERIAL_BAUD_460800, - SERIAL_BAUD_500000, - SERIAL_BAUD_576000, - SERIAL_BAUD_921600, - SERIAL_BAUD_1000000, - SERIAL_BAUD_1500000, - SERIAL_BAUD_2000000, - - SERIAL_BAUD_INVALID -} serial_baud_t; - -typedef enum { - SERIAL_STOPBIT_1, - SERIAL_STOPBIT_2, - - SERIAL_STOPBIT_INVALID -} serial_stopbit_t; - -typedef enum { - GPIO_RTS = 1, - GPIO_DTR, - GPIO_BRK, -} serial_gpio_t; - -/* common helper functions */ -serial_baud_t serial_get_baud(const unsigned int baud); -unsigned int serial_get_baud_int(const serial_baud_t baud); -serial_bits_t serial_get_bits(const char *mode); -unsigned int serial_get_bits_int(const serial_bits_t bits); -serial_parity_t serial_get_parity(const char *mode); -char serial_get_parity_str(const serial_parity_t parity); -serial_stopbit_t serial_get_stopbit(const char *mode); -unsigned int serial_get_stopbit_int(const serial_stopbit_t stopbit); - -#endif diff --git a/linux/src/stm32flash_serial/src/serial_common.c b/linux/src/stm32flash_serial/src/serial_common.c deleted file mode 100644 index 43e48e1ac..000000000 --- a/linux/src/stm32flash_serial/src/serial_common.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "serial.h" - -serial_baud_t serial_get_baud(const unsigned int baud) { - switch(baud) { - case 1200: return SERIAL_BAUD_1200 ; - case 1800: return SERIAL_BAUD_1800 ; - case 2400: return SERIAL_BAUD_2400 ; - case 4800: return SERIAL_BAUD_4800 ; - case 9600: return SERIAL_BAUD_9600 ; - case 19200: return SERIAL_BAUD_19200 ; - case 38400: return SERIAL_BAUD_38400 ; - case 57600: return SERIAL_BAUD_57600 ; - case 115200: return SERIAL_BAUD_115200; - case 128000: return SERIAL_BAUD_128000; - case 230400: return SERIAL_BAUD_230400; - case 256000: return SERIAL_BAUD_256000; - case 460800: return SERIAL_BAUD_460800; - case 500000: return SERIAL_BAUD_500000; - case 576000: return SERIAL_BAUD_576000; - case 921600: return SERIAL_BAUD_921600; - case 1000000: return SERIAL_BAUD_1000000; - case 1500000: return SERIAL_BAUD_1500000; - case 2000000: return SERIAL_BAUD_2000000; - - default: - return SERIAL_BAUD_INVALID; - } -} - -unsigned int serial_get_baud_int(const serial_baud_t baud) { - switch(baud) { - case SERIAL_BAUD_1200 : return 1200 ; - case SERIAL_BAUD_1800 : return 1800 ; - case SERIAL_BAUD_2400 : return 2400 ; - case SERIAL_BAUD_4800 : return 4800 ; - case SERIAL_BAUD_9600 : return 9600 ; - case SERIAL_BAUD_19200 : return 19200 ; - case SERIAL_BAUD_38400 : return 38400 ; - case SERIAL_BAUD_57600 : return 57600 ; - case SERIAL_BAUD_115200: return 115200; - case SERIAL_BAUD_128000: return 128000; - case SERIAL_BAUD_230400: return 230400; - case SERIAL_BAUD_256000: return 256000; - case SERIAL_BAUD_460800: return 460800; - case SERIAL_BAUD_500000: return 500000; - case SERIAL_BAUD_576000: return 576000; - case SERIAL_BAUD_921600: return 921600; - case SERIAL_BAUD_1000000: return 1000000; - case SERIAL_BAUD_1500000: return 1500000; - case SERIAL_BAUD_2000000: return 2000000; - - case SERIAL_BAUD_INVALID: - default: - return 0; - } -} - -serial_bits_t serial_get_bits(const char *mode) { - if (!mode) - return SERIAL_BITS_INVALID; - switch(mode[0]) { - case '5': return SERIAL_BITS_5; - case '6': return SERIAL_BITS_6; - case '7': return SERIAL_BITS_7; - case '8': return SERIAL_BITS_8; - - default: - return SERIAL_BITS_INVALID; - } -} - -unsigned int serial_get_bits_int(const serial_bits_t bits) { - switch(bits) { - case SERIAL_BITS_5: return 5; - case SERIAL_BITS_6: return 6; - case SERIAL_BITS_7: return 7; - case SERIAL_BITS_8: return 8; - - default: - return 0; - } -} - -serial_parity_t serial_get_parity(const char *mode) { - if (!mode || !mode[0]) - return SERIAL_PARITY_INVALID; - switch(mode[1]) { - case 'N': - case 'n': - return SERIAL_PARITY_NONE; - case 'E': - case 'e': - return SERIAL_PARITY_EVEN; - case 'O': - case 'o': - return SERIAL_PARITY_ODD; - - default: - return SERIAL_PARITY_INVALID; - } -} - -char serial_get_parity_str(const serial_parity_t parity) { - switch(parity) { - case SERIAL_PARITY_NONE: return 'N'; - case SERIAL_PARITY_EVEN: return 'E'; - case SERIAL_PARITY_ODD : return 'O'; - - default: - return ' '; - } -} - -serial_stopbit_t serial_get_stopbit(const char *mode) { - if (!mode || !mode[0] || !mode[1]) - return SERIAL_STOPBIT_INVALID; - switch(mode[2]) { - case '1': return SERIAL_STOPBIT_1; - case '2': return SERIAL_STOPBIT_2; - - default: - return SERIAL_STOPBIT_INVALID; - } -} - -unsigned int serial_get_stopbit_int(const serial_stopbit_t stopbit) { - switch(stopbit) { - case SERIAL_STOPBIT_1: return 1; - case SERIAL_STOPBIT_2: return 2; - - default: - return 0; - } -} - diff --git a/linux/src/stm32flash_serial/src/serial_platform.c b/linux/src/stm32flash_serial/src/serial_platform.c deleted file mode 100644 index 98e256921..000000000 --- a/linux/src/stm32flash_serial/src/serial_platform.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined(__WIN32__) || defined(__CYGWIN__) -# include "serial_w32.c" -#else -# include "serial_posix.c" -#endif diff --git a/linux/src/stm32flash_serial/src/serial_posix.c b/linux/src/stm32flash_serial/src/serial_posix.c deleted file mode 100644 index 284b35b20..000000000 --- a/linux/src/stm32flash_serial/src/serial_posix.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - -struct serial { - int fd; - struct termios oldtio; - struct termios newtio; - char setup_str[11]; -}; - -static serial_t *serial_open(const char *device) -{ - serial_t *h = calloc(sizeof(serial_t), 1); - - h->fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); - if (h->fd < 0) { - free(h); - return NULL; - } - fcntl(h->fd, F_SETFL, 0); - - tcgetattr(h->fd, &h->oldtio); - tcgetattr(h->fd, &h->newtio); - - return h; -} - -static void serial_flush(const serial_t *h) -{ - tcflush(h->fd, TCIFLUSH); -} - -static void serial_close(serial_t *h) -{ - serial_flush(h); - tcsetattr(h->fd, TCSANOW, &h->oldtio); - close(h->fd); - free(h); -} - -static port_err_t serial_setup(serial_t *h, const serial_baud_t baud, - const serial_bits_t bits, - const serial_parity_t parity, - const serial_stopbit_t stopbit) -{ - speed_t port_baud; - tcflag_t port_bits; - tcflag_t port_parity; - tcflag_t port_stop; - struct termios settings; - - switch (baud) { - case SERIAL_BAUD_1200: port_baud = B1200; break; - case SERIAL_BAUD_1800: port_baud = B1800; break; - case SERIAL_BAUD_2400: port_baud = B2400; break; - case SERIAL_BAUD_4800: port_baud = B4800; break; - case SERIAL_BAUD_9600: port_baud = B9600; break; - case SERIAL_BAUD_19200: port_baud = B19200; break; - case SERIAL_BAUD_38400: port_baud = B38400; break; - case SERIAL_BAUD_57600: port_baud = B57600; break; - case SERIAL_BAUD_115200: port_baud = B115200; break; - case SERIAL_BAUD_230400: port_baud = B230400; break; -#ifdef B460800 - case SERIAL_BAUD_460800: port_baud = B460800; break; -#endif /* B460800 */ -#ifdef B921600 - case SERIAL_BAUD_921600: port_baud = B921600; break; -#endif /* B921600 */ -#ifdef B500000 - case SERIAL_BAUD_500000: port_baud = B500000; break; -#endif /* B500000 */ -#ifdef B576000 - case SERIAL_BAUD_576000: port_baud = B576000; break; -#endif /* B576000 */ -#ifdef B1000000 - case SERIAL_BAUD_1000000: port_baud = B1000000; break; -#endif /* B1000000 */ -#ifdef B1500000 - case SERIAL_BAUD_1500000: port_baud = B1500000; break; -#endif /* B1500000 */ -#ifdef B2000000 - case SERIAL_BAUD_2000000: port_baud = B2000000; break; -#endif /* B2000000 */ - - case SERIAL_BAUD_INVALID: - default: - return PORT_ERR_UNKNOWN; - } - - switch (bits) { - case SERIAL_BITS_5: port_bits = CS5; break; - case SERIAL_BITS_6: port_bits = CS6; break; - case SERIAL_BITS_7: port_bits = CS7; break; - case SERIAL_BITS_8: port_bits = CS8; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (parity) { - case SERIAL_PARITY_NONE: port_parity = 0; break; - case SERIAL_PARITY_EVEN: port_parity = PARENB; break; - case SERIAL_PARITY_ODD: port_parity = PARENB | PARODD; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (stopbit) { - case SERIAL_STOPBIT_1: port_stop = 0; break; - case SERIAL_STOPBIT_2: port_stop = CSTOPB; break; - - default: - return PORT_ERR_UNKNOWN; - } - - /* reset the settings */ -#ifndef __sun /* Used by GNU and BSD. Ignore __SVR4 in test. */ - cfmakeraw(&h->newtio); -#else /* __sun */ - h->newtio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR - | IGNCR | ICRNL | IXON); - if (port_parity) - h->newtio.c_iflag |= INPCK; - - h->newtio.c_oflag &= ~OPOST; - h->newtio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - h->newtio.c_cflag &= ~(CSIZE | PARENB); - h->newtio.c_cflag |= CS8; -#endif /* __sun */ -#ifdef __QNXNTO__ - h->newtio.c_cflag &= ~(CSIZE | IHFLOW | OHFLOW); -#else - h->newtio.c_cflag &= ~(CSIZE | CRTSCTS); -#endif - h->newtio.c_cflag &= ~(CSIZE | CRTSCTS); - h->newtio.c_iflag &= ~(IXON | IXOFF | IXANY | IGNPAR); - h->newtio.c_lflag &= ~(ECHOK | ECHOCTL | ECHOKE); - h->newtio.c_oflag &= ~(OPOST | ONLCR); - - /* setup the new settings */ - cfsetispeed(&h->newtio, port_baud); - cfsetospeed(&h->newtio, port_baud); - h->newtio.c_cflag |= - port_parity | - port_bits | - port_stop | - CLOCAL | - CREAD; - - h->newtio.c_cc[VMIN] = 0; - h->newtio.c_cc[VTIME] = 5; /* in units of 0.1 s */ - - /* set the settings */ - serial_flush(h); - if (tcsetattr(h->fd, TCSANOW, &h->newtio) != 0) - return PORT_ERR_UNKNOWN; - -/* this check fails on CDC-ACM devices, bits 16 and 17 of cflag differ! - * it has been disabled below for now -jcw, 2015-11-09 - if (settings.c_cflag != h->newtio.c_cflag) - fprintf(stderr, "c_cflag mismatch %lx\n", - settings.c_cflag ^ h->newtio.c_cflag); - */ - - /* confirm they were set */ - tcgetattr(h->fd, &settings); - if (settings.c_iflag != h->newtio.c_iflag || - settings.c_oflag != h->newtio.c_oflag || - //settings.c_cflag != h->newtio.c_cflag || - settings.c_lflag != h->newtio.c_lflag) - return PORT_ERR_UNKNOWN; - - snprintf(h->setup_str, sizeof(h->setup_str), "%u %d%c%d", - serial_get_baud_int(baud), - serial_get_bits_int(bits), - serial_get_parity_str(parity), - serial_get_stopbit_int(stopbit)); - return PORT_ERR_OK; -} - -/* - * Roger clark. - * This function is no longer used. But has just been commented out in case it needs - * to be reinstated in the future - -static int startswith(const char *haystack, const char *needle) { - return strncmp(haystack, needle, strlen(needle)) == 0; -} -*/ - -static int is_tty(const char *path) { - char resolved[PATH_MAX]; - - if(!realpath(path, resolved)) return 0; - - - /* - * Roger Clark - * Commented out this check, because on OSX some devices are /dev/cu - * and some users use symbolic links to devices, hence the name may not even start - * with /dev - - if(startswith(resolved, "/dev/tty")) return 1; - - return 0; - */ - - return 1; -} - -static port_err_t serial_posix_open(struct port_interface *port, - struct port_options *ops) -{ - serial_t *h; - - /* 1. check device name match */ - if (!is_tty(ops->device)) - return PORT_ERR_NODEV; - - /* 2. check options */ - if (ops->baudRate == SERIAL_BAUD_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_parity(ops->serial_mode) == SERIAL_PARITY_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) - return PORT_ERR_UNKNOWN; - - /* 3. open it */ - h = serial_open(ops->device); - if (h == NULL) - return PORT_ERR_UNKNOWN; - - /* 4. set options */ - if (serial_setup(h, ops->baudRate, - serial_get_bits(ops->serial_mode), - serial_get_parity(ops->serial_mode), - serial_get_stopbit(ops->serial_mode) - ) != PORT_ERR_OK) { - serial_close(h); - return PORT_ERR_UNKNOWN; - } - - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t serial_posix_close(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - serial_close(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t serial_posix_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - ssize_t r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - r = read(h->fd, pos, nbyte); - if (r == 0) - return PORT_ERR_TIMEDOUT; - if (r < 0) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_posix_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - ssize_t r; - const uint8_t *pos = (const uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - r = write(h->fd, pos, nbyte); - if (r < 1) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_posix_gpio(struct port_interface *port, - serial_gpio_t n, int level) -{ - serial_t *h; - int bit, lines; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - switch (n) { - case GPIO_RTS: - bit = TIOCM_RTS; - break; - - case GPIO_DTR: - bit = TIOCM_DTR; - break; - - case GPIO_BRK: - if (level == 0) - return PORT_ERR_OK; - if (tcsendbreak(h->fd, 1)) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; - - default: - return PORT_ERR_UNKNOWN; - } - - /* handle RTS/DTR */ - if (ioctl(h->fd, TIOCMGET, &lines)) - return PORT_ERR_UNKNOWN; - lines = level ? lines | bit : lines & ~bit; - if (ioctl(h->fd, TIOCMSET, &lines)) - return PORT_ERR_UNKNOWN; - - return PORT_ERR_OK; -} - -static const char *serial_posix_get_cfg_str(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - return h ? h->setup_str : "INVALID"; -} - -struct port_interface port_serial = { - .name = "serial_posix", - .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, - .open = serial_posix_open, - .close = serial_posix_close, - .read = serial_posix_read, - .write = serial_posix_write, - .gpio = serial_posix_gpio, - .get_cfg_str = serial_posix_get_cfg_str, -}; diff --git a/linux/src/stm32flash_serial/src/serial_w32.c b/linux/src/stm32flash_serial/src/serial_w32.c deleted file mode 100644 index 56772c0a0..000000000 --- a/linux/src/stm32flash_serial/src/serial_w32.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2010 Gareth McMullin - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - -struct serial { - HANDLE fd; - DCB oldtio; - DCB newtio; - char setup_str[11]; -}; - -static serial_t *serial_open(const char *device) -{ - serial_t *h = calloc(sizeof(serial_t), 1); - char *devName; - - /* timeout in ms */ - COMMTIMEOUTS timeouts = {MAXDWORD, MAXDWORD, 500, 0, 0}; - - /* Fix the device name if required */ - if (strlen(device) > 4 && device[0] != '\\') { - devName = calloc(1, strlen(device) + 5); - sprintf(devName, "\\\\.\\%s", device); - } else { - devName = (char *)device; - } - - /* Create file handle for port */ - h->fd = CreateFile(devName, GENERIC_READ | GENERIC_WRITE, - 0, /* Exclusive access */ - NULL, /* No security */ - OPEN_EXISTING, - 0, /* No overlap */ - NULL); - - if (devName != device) - free(devName); - - if (h->fd == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_FILE_NOT_FOUND) - fprintf(stderr, "File not found: %s\n", device); - return NULL; - } - - SetupComm(h->fd, 4096, 4096); /* Set input and output buffer size */ - - SetCommTimeouts(h->fd, &timeouts); - - SetCommMask(h->fd, EV_ERR); /* Notify us of error events */ - - GetCommState(h->fd, &h->oldtio); /* Retrieve port parameters */ - GetCommState(h->fd, &h->newtio); /* Retrieve port parameters */ - - /* PurgeComm(h->fd, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); */ - - return h; -} - -static void serial_flush(const serial_t *h) -{ - /* We shouldn't need to flush in non-overlapping (blocking) mode */ - /* tcflush(h->fd, TCIFLUSH); */ -} - -static void serial_close(serial_t *h) -{ - serial_flush(h); - SetCommState(h->fd, &h->oldtio); - CloseHandle(h->fd); - free(h); -} - -static port_err_t serial_setup(serial_t *h, - const serial_baud_t baud, - const serial_bits_t bits, - const serial_parity_t parity, - const serial_stopbit_t stopbit) -{ - switch (baud) { - case SERIAL_BAUD_1200: h->newtio.BaudRate = CBR_1200; break; - /* case SERIAL_BAUD_1800: h->newtio.BaudRate = CBR_1800; break; */ - case SERIAL_BAUD_2400: h->newtio.BaudRate = CBR_2400; break; - case SERIAL_BAUD_4800: h->newtio.BaudRate = CBR_4800; break; - case SERIAL_BAUD_9600: h->newtio.BaudRate = CBR_9600; break; - case SERIAL_BAUD_19200: h->newtio.BaudRate = CBR_19200; break; - case SERIAL_BAUD_38400: h->newtio.BaudRate = CBR_38400; break; - case SERIAL_BAUD_57600: h->newtio.BaudRate = CBR_57600; break; - case SERIAL_BAUD_115200: h->newtio.BaudRate = CBR_115200; break; - case SERIAL_BAUD_128000: h->newtio.BaudRate = CBR_128000; break; - case SERIAL_BAUD_256000: h->newtio.BaudRate = CBR_256000; break; - /* These are not defined in WinBase.h and might work or not */ - case SERIAL_BAUD_230400: h->newtio.BaudRate = 230400; break; - case SERIAL_BAUD_460800: h->newtio.BaudRate = 460800; break; - case SERIAL_BAUD_500000: h->newtio.BaudRate = 500000; break; - case SERIAL_BAUD_576000: h->newtio.BaudRate = 576000; break; - case SERIAL_BAUD_921600: h->newtio.BaudRate = 921600; break; - case SERIAL_BAUD_1000000: h->newtio.BaudRate = 1000000; break; - case SERIAL_BAUD_1500000: h->newtio.BaudRate = 1500000; break; - case SERIAL_BAUD_2000000: h->newtio.BaudRate = 2000000; break; - case SERIAL_BAUD_INVALID: - - default: - return PORT_ERR_UNKNOWN; - } - - switch (bits) { - case SERIAL_BITS_5: h->newtio.ByteSize = 5; break; - case SERIAL_BITS_6: h->newtio.ByteSize = 6; break; - case SERIAL_BITS_7: h->newtio.ByteSize = 7; break; - case SERIAL_BITS_8: h->newtio.ByteSize = 8; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (parity) { - case SERIAL_PARITY_NONE: h->newtio.Parity = NOPARITY; break; - case SERIAL_PARITY_EVEN: h->newtio.Parity = EVENPARITY; break; - case SERIAL_PARITY_ODD: h->newtio.Parity = ODDPARITY; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (stopbit) { - case SERIAL_STOPBIT_1: h->newtio.StopBits = ONESTOPBIT; break; - case SERIAL_STOPBIT_2: h->newtio.StopBits = TWOSTOPBITS; break; - - default: - return PORT_ERR_UNKNOWN; - } - - /* reset the settings */ - h->newtio.fOutxCtsFlow = FALSE; - h->newtio.fOutxDsrFlow = FALSE; - h->newtio.fOutX = FALSE; - h->newtio.fInX = FALSE; - h->newtio.fNull = 0; - h->newtio.fAbortOnError = 0; - - /* set the settings */ - serial_flush(h); - if (!SetCommState(h->fd, &h->newtio)) - return PORT_ERR_UNKNOWN; - - snprintf(h->setup_str, sizeof(h->setup_str), "%u %d%c%d", - serial_get_baud_int(baud), - serial_get_bits_int(bits), - serial_get_parity_str(parity), - serial_get_stopbit_int(stopbit) - ); - return PORT_ERR_OK; -} - -static port_err_t serial_w32_open(struct port_interface *port, - struct port_options *ops) -{ - serial_t *h; - - /* 1. check device name match */ - if (!((strlen(ops->device) == 4 || strlen(ops->device) == 5) - && !strncmp(ops->device, "COM", 3) && isdigit(ops->device[3])) - && !(!strncmp(ops->device, "\\\\.\\COM", strlen("\\\\.\\COM")) - && isdigit(ops->device[strlen("\\\\.\\COM")]))) - return PORT_ERR_NODEV; - - /* 2. check options */ - if (ops->baudRate == SERIAL_BAUD_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_parity(ops->serial_mode) == SERIAL_PARITY_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) - return PORT_ERR_UNKNOWN; - - /* 3. open it */ - h = serial_open(ops->device); - if (h == NULL) - return PORT_ERR_UNKNOWN; - - /* 4. set options */ - if (serial_setup(h, ops->baudRate, - serial_get_bits(ops->serial_mode), - serial_get_parity(ops->serial_mode), - serial_get_stopbit(ops->serial_mode) - ) != PORT_ERR_OK) { - serial_close(h); - return PORT_ERR_UNKNOWN; - } - - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t serial_w32_close(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - serial_close(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t serial_w32_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - DWORD r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - ReadFile(h->fd, pos, nbyte, &r, NULL); - if (r == 0) - return PORT_ERR_TIMEDOUT; - if (r < 0) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_w32_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - DWORD r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - if (!WriteFile(h->fd, pos, nbyte, &r, NULL)) - return PORT_ERR_UNKNOWN; - if (r < 1) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_w32_gpio(struct port_interface *port, - serial_gpio_t n, int level) -{ - serial_t *h; - int bit; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - switch (n) { - case GPIO_RTS: - bit = level ? SETRTS : CLRRTS; - break; - - case GPIO_DTR: - bit = level ? SETDTR : CLRDTR; - break; - - case GPIO_BRK: - if (level == 0) - return PORT_ERR_OK; - if (EscapeCommFunction(h->fd, SETBREAK) == 0) - return PORT_ERR_UNKNOWN; - usleep(500000); - if (EscapeCommFunction(h->fd, CLRBREAK) == 0) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; - - default: - return PORT_ERR_UNKNOWN; - } - - /* handle RTS/DTR */ - if (EscapeCommFunction(h->fd, bit) == 0) - return PORT_ERR_UNKNOWN; - - return PORT_ERR_OK; -} - -static const char *serial_w32_get_cfg_str(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - return h ? h->setup_str : "INVALID"; -} - -struct port_interface port_serial = { - .name = "serial_w32", - .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, - .open = serial_w32_open, - .close = serial_w32_close, - .read = serial_w32_read, - .write = serial_w32_write, - .gpio = serial_w32_gpio, - .get_cfg_str = serial_w32_get_cfg_str, -}; diff --git a/linux/src/stm32flash_serial/src/stm32.c b/linux/src/stm32flash_serial/src/stm32.c deleted file mode 100644 index 74047d244..000000000 --- a/linux/src/stm32flash_serial/src/stm32.c +++ /dev/null @@ -1,1048 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright 2010 Geoffrey McRae - Copyright 2012-2014 Tormod Volden - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include - -#include "stm32.h" -#include "port.h" -#include "utils.h" - -#define STM32_ACK 0x79 -#define STM32_NACK 0x1F -#define STM32_BUSY 0x76 - -#define STM32_CMD_INIT 0x7F -#define STM32_CMD_GET 0x00 /* get the version and command supported */ -#define STM32_CMD_GVR 0x01 /* get version and read protection status */ -#define STM32_CMD_GID 0x02 /* get ID */ -#define STM32_CMD_RM 0x11 /* read memory */ -#define STM32_CMD_GO 0x21 /* go */ -#define STM32_CMD_WM 0x31 /* write memory */ -#define STM32_CMD_WM_NS 0x32 /* no-stretch write memory */ -#define STM32_CMD_ER 0x43 /* erase */ -#define STM32_CMD_EE 0x44 /* extended erase */ -#define STM32_CMD_EE_NS 0x45 /* extended erase no-stretch */ -#define STM32_CMD_WP 0x63 /* write protect */ -#define STM32_CMD_WP_NS 0x64 /* write protect no-stretch */ -#define STM32_CMD_UW 0x73 /* write unprotect */ -#define STM32_CMD_UW_NS 0x74 /* write unprotect no-stretch */ -#define STM32_CMD_RP 0x82 /* readout protect */ -#define STM32_CMD_RP_NS 0x83 /* readout protect no-stretch */ -#define STM32_CMD_UR 0x92 /* readout unprotect */ -#define STM32_CMD_UR_NS 0x93 /* readout unprotect no-stretch */ -#define STM32_CMD_CRC 0xA1 /* compute CRC */ -#define STM32_CMD_ERR 0xFF /* not a valid command */ - -#define STM32_RESYNC_TIMEOUT 35 /* seconds */ -#define STM32_MASSERASE_TIMEOUT 35 /* seconds */ -#define STM32_SECTERASE_TIMEOUT 5 /* seconds */ -#define STM32_BLKWRITE_TIMEOUT 1 /* seconds */ -#define STM32_WUNPROT_TIMEOUT 1 /* seconds */ -#define STM32_WPROT_TIMEOUT 1 /* seconds */ -#define STM32_RPROT_TIMEOUT 1 /* seconds */ - -#define STM32_CMD_GET_LENGTH 17 /* bytes in the reply */ - -struct stm32_cmd { - uint8_t get; - uint8_t gvr; - uint8_t gid; - uint8_t rm; - uint8_t go; - uint8_t wm; - uint8_t er; /* this may be extended erase */ - uint8_t wp; - uint8_t uw; - uint8_t rp; - uint8_t ur; - uint8_t crc; -}; - -/* Reset code for ARMv7-M (Cortex-M3) and ARMv6-M (Cortex-M0) - * see ARMv7-M or ARMv6-M Architecture Reference Manual (table B3-8) - * or "The definitive guide to the ARM Cortex-M3", section 14.4. - */ -static const uint8_t stm_reset_code[] = { - 0x01, 0x49, // ldr r1, [pc, #4] ; () - 0x02, 0x4A, // ldr r2, [pc, #8] ; () - 0x0A, 0x60, // str r2, [r1, #0] - 0xfe, 0xe7, // endless: b endless - 0x0c, 0xed, 0x00, 0xe0, // .word 0xe000ed0c = NVIC AIRCR register address - 0x04, 0x00, 0xfa, 0x05 // .word 0x05fa0004 = VECTKEY | SYSRESETREQ -}; - -static const uint32_t stm_reset_code_length = sizeof(stm_reset_code); - -extern const stm32_dev_t devices[]; - -static void stm32_warn_stretching(const char *f) -{ - fprintf(stderr, "Attention !!!\n"); - fprintf(stderr, "\tThis %s error could be caused by your I2C\n", f); - fprintf(stderr, "\tcontroller not accepting \"clock stretching\"\n"); - fprintf(stderr, "\tas required by bootloader.\n"); - fprintf(stderr, "\tCheck \"I2C.txt\" in stm32flash source code.\n"); -} - -static stm32_err_t stm32_get_ack_timeout(const stm32_t *stm, time_t timeout) -{ - struct port_interface *port = stm->port; - uint8_t byte; - port_err_t p_err; - time_t t0, t1; - - if (!(port->flags & PORT_RETRY)) - timeout = 0; - - if (timeout) - time(&t0); - - do { - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_TIMEDOUT && timeout) { - time(&t1); - if (t1 < t0 + timeout) - continue; - } - - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to read ACK byte\n"); - return STM32_ERR_UNKNOWN; - } - - if (byte == STM32_ACK) - return STM32_ERR_OK; - if (byte == STM32_NACK) - return STM32_ERR_NACK; - if (byte != STM32_BUSY) { - fprintf(stderr, "Got byte 0x%02x instead of ACK\n", - byte); - return STM32_ERR_UNKNOWN; - } - } while (1); -} - -static stm32_err_t stm32_get_ack(const stm32_t *stm) -{ - return stm32_get_ack_timeout(stm, 0); -} - -static stm32_err_t stm32_send_command_timeout(const stm32_t *stm, - const uint8_t cmd, - time_t timeout) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - port_err_t p_err; - uint8_t buf[2]; - - buf[0] = cmd; - buf[1] = cmd ^ 0xFF; - p_err = port->write(port, buf, 2); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send command\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, timeout); - if (s_err == STM32_ERR_OK) - return STM32_ERR_OK; - if (s_err == STM32_ERR_NACK) - fprintf(stderr, "Got NACK from device on command 0x%02x\n", cmd); - else - fprintf(stderr, "Unexpected reply from device on command 0x%02x\n", cmd); - return STM32_ERR_UNKNOWN; -} - -static stm32_err_t stm32_send_command(const stm32_t *stm, const uint8_t cmd) -{ - return stm32_send_command_timeout(stm, cmd, 0); -} - -/* if we have lost sync, send a wrong command and expect a NACK */ -static stm32_err_t stm32_resync(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - uint8_t buf[2], ack; - time_t t0, t1; - - time(&t0); - t1 = t0; - - buf[0] = STM32_CMD_ERR; - buf[1] = STM32_CMD_ERR ^ 0xFF; - while (t1 < t0 + STM32_RESYNC_TIMEOUT) { - p_err = port->write(port, buf, 2); - if (p_err != PORT_ERR_OK) { - usleep(500000); - time(&t1); - continue; - } - p_err = port->read(port, &ack, 1); - if (p_err != PORT_ERR_OK) { - time(&t1); - continue; - } - if (ack == STM32_NACK) - return STM32_ERR_OK; - time(&t1); - } - return STM32_ERR_UNKNOWN; -} - -/* - * some command receive reply frame with variable length, and length is - * embedded in reply frame itself. - * We can guess the length, but if we guess wrong the protocol gets out - * of sync. - * Use resync for frame oriented interfaces (e.g. I2C) and byte-by-byte - * read for byte oriented interfaces (e.g. UART). - * - * to run safely, data buffer should be allocated for 256+1 bytes - * - * len is value of the first byte in the frame. - */ -static stm32_err_t stm32_guess_len_cmd(const stm32_t *stm, uint8_t cmd, - uint8_t *data, unsigned int len) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - if (port->flags & PORT_BYTE) { - /* interface is UART-like */ - p_err = port->read(port, data, 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - len = data[0]; - p_err = port->read(port, data + 1, len + 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; - } - - p_err = port->read(port, data, len + 2); - if (p_err == PORT_ERR_OK && len == data[0]) - return STM32_ERR_OK; - if (p_err != PORT_ERR_OK) { - /* restart with only one byte */ - if (stm32_resync(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - p_err = port->read(port, data, 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - } - - fprintf(stderr, "Re sync (len = %d)\n", data[0]); - if (stm32_resync(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - len = data[0]; - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - p_err = port->read(port, data, len + 2); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; -} - -/* - * Some interface, e.g. UART, requires a specific init sequence to let STM32 - * autodetect the interface speed. - * The sequence is only required one time after reset. - * stm32flash has command line flag "-c" to prevent sending the init sequence - * in case it was already sent before. - * User can easily forget adding "-c". In this case the bootloader would - * interpret the init sequence as part of a command message, then waiting for - * the rest of the message blocking the interface. - * This function sends the init sequence and, in case of timeout, recovers - * the interface. - */ -static stm32_err_t stm32_send_init_seq(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - uint8_t byte, cmd = STM32_CMD_INIT; - - p_err = port->write(port, &cmd, 1); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send init to device\n"); - return STM32_ERR_UNKNOWN; - } - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_OK && byte == STM32_ACK) - return STM32_ERR_OK; - if (p_err == PORT_ERR_OK && byte == STM32_NACK) { - /* We could get error later, but let's continue, for now. */ - fprintf(stderr, - "Warning: the interface was not closed properly.\n"); - return STM32_ERR_OK; - } - if (p_err != PORT_ERR_TIMEDOUT) { - fprintf(stderr, "Failed to init device.\n"); - return STM32_ERR_UNKNOWN; - } - - /* - * Check if previous STM32_CMD_INIT was taken as first byte - * of a command. Send a new byte, we should get back a NACK. - */ - p_err = port->write(port, &cmd, 1); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send init to device\n"); - return STM32_ERR_UNKNOWN; - } - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_OK && byte == STM32_NACK) - return STM32_ERR_OK; - fprintf(stderr, "Failed to init device.\n"); - return STM32_ERR_UNKNOWN; -} - -/* find newer command by higher code */ -#define newer(prev, a) (((prev) == STM32_CMD_ERR) \ - ? (a) \ - : (((prev) > (a)) ? (prev) : (a))) - -stm32_t *stm32_init(struct port_interface *port, const char init) -{ - uint8_t len, val, buf[257]; - stm32_t *stm; - int i, new_cmds; - - stm = calloc(sizeof(stm32_t), 1); - stm->cmd = malloc(sizeof(stm32_cmd_t)); - memset(stm->cmd, STM32_CMD_ERR, sizeof(stm32_cmd_t)); - stm->port = port; - - if ((port->flags & PORT_CMD_INIT) && init) - if (stm32_send_init_seq(stm) != STM32_ERR_OK) - return NULL; - - /* get the version and read protection status */ - if (stm32_send_command(stm, STM32_CMD_GVR) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - /* From AN, only UART bootloader returns 3 bytes */ - len = (port->flags & PORT_GVR_ETX) ? 3 : 1; - if (port->read(port, buf, len) != PORT_ERR_OK) - return NULL; - stm->version = buf[0]; - stm->option1 = (port->flags & PORT_GVR_ETX) ? buf[1] : 0; - stm->option2 = (port->flags & PORT_GVR_ETX) ? buf[2] : 0; - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - /* get the bootloader information */ - len = STM32_CMD_GET_LENGTH; - if (port->cmd_get_reply) - for (i = 0; port->cmd_get_reply[i].length; i++) - if (stm->version == port->cmd_get_reply[i].version) { - len = port->cmd_get_reply[i].length; - break; - } - if (stm32_guess_len_cmd(stm, STM32_CMD_GET, buf, len) != STM32_ERR_OK) - return NULL; - len = buf[0] + 1; - stm->bl_version = buf[1]; - new_cmds = 0; - for (i = 1; i < len; i++) { - val = buf[i + 1]; - switch (val) { - case STM32_CMD_GET: - stm->cmd->get = val; break; - case STM32_CMD_GVR: - stm->cmd->gvr = val; break; - case STM32_CMD_GID: - stm->cmd->gid = val; break; - case STM32_CMD_RM: - stm->cmd->rm = val; break; - case STM32_CMD_GO: - stm->cmd->go = val; break; - case STM32_CMD_WM: - case STM32_CMD_WM_NS: - stm->cmd->wm = newer(stm->cmd->wm, val); - break; - case STM32_CMD_ER: - case STM32_CMD_EE: - case STM32_CMD_EE_NS: - stm->cmd->er = newer(stm->cmd->er, val); - break; - case STM32_CMD_WP: - case STM32_CMD_WP_NS: - stm->cmd->wp = newer(stm->cmd->wp, val); - break; - case STM32_CMD_UW: - case STM32_CMD_UW_NS: - stm->cmd->uw = newer(stm->cmd->uw, val); - break; - case STM32_CMD_RP: - case STM32_CMD_RP_NS: - stm->cmd->rp = newer(stm->cmd->rp, val); - break; - case STM32_CMD_UR: - case STM32_CMD_UR_NS: - stm->cmd->ur = newer(stm->cmd->ur, val); - break; - case STM32_CMD_CRC: - stm->cmd->crc = newer(stm->cmd->crc, val); - break; - default: - if (new_cmds++ == 0) - fprintf(stderr, - "GET returns unknown commands (0x%2x", - val); - else - fprintf(stderr, ", 0x%2x", val); - } - } - if (new_cmds) - fprintf(stderr, ")\n"); - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - if (stm->cmd->get == STM32_CMD_ERR - || stm->cmd->gvr == STM32_CMD_ERR - || stm->cmd->gid == STM32_CMD_ERR) { - fprintf(stderr, "Error: bootloader did not returned correct information from GET command\n"); - return NULL; - } - - /* get the device ID */ - if (stm32_guess_len_cmd(stm, stm->cmd->gid, buf, 1) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - len = buf[0] + 1; - if (len < 2) { - stm32_close(stm); - fprintf(stderr, "Only %d bytes sent in the PID, unknown/unsupported device\n", len); - return NULL; - } - stm->pid = (buf[1] << 8) | buf[2]; - if (len > 2) { - fprintf(stderr, "This bootloader returns %d extra bytes in PID:", len); - for (i = 2; i <= len ; i++) - fprintf(stderr, " %02x", buf[i]); - fprintf(stderr, "\n"); - } - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - stm->dev = devices; - while (stm->dev->id != 0x00 && stm->dev->id != stm->pid) - ++stm->dev; - - if (!stm->dev->id) { - fprintf(stderr, "Unknown/unsupported device (Device ID: 0x%03x)\n", stm->pid); - stm32_close(stm); - return NULL; - } - - return stm; -} - -void stm32_close(stm32_t *stm) -{ - if (stm) - free(stm->cmd); - free(stm); -} - -stm32_err_t stm32_read_memory(const stm32_t *stm, uint32_t address, - uint8_t data[], unsigned int len) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (!len) - return STM32_ERR_OK; - - if (len > 256) { - fprintf(stderr, "Error: READ length limit at 256 bytes\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->rm == STM32_CMD_ERR) { - fprintf(stderr, "Error: READ command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->rm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_send_command(stm, len - 1) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (port->read(port, data, len) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - return STM32_ERR_OK; -} - -stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, - const uint8_t data[], unsigned int len) -{ - struct port_interface *port = stm->port; - uint8_t cs, buf[256 + 2]; - unsigned int i, aligned_len; - stm32_err_t s_err; - - if (!len) - return STM32_ERR_OK; - - if (len > 256) { - fprintf(stderr, "Error: READ length limit at 256 bytes\n"); - return STM32_ERR_UNKNOWN; - } - - /* must be 32bit aligned */ - if (address & 0x3 || len & 0x3) { - fprintf(stderr, "Error: WRITE address and length must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->wm == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - /* send the address and checksum */ - if (stm32_send_command(stm, stm->cmd->wm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - aligned_len = (len + 3) & ~3; - cs = aligned_len - 1; - buf[0] = aligned_len - 1; - for (i = 0; i < len; i++) { - cs ^= data[i]; - buf[i + 1] = data[i]; - } - /* padding data */ - for (i = len; i < aligned_len; i++) { - cs ^= 0xFF; - buf[i + 1] = 0xFF; - } - buf[aligned_len + 1] = cs; - if (port->write(port, buf, aligned_len + 2) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_BLKWRITE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->wm != STM32_CMD_WM_NS) - stm32_warn_stretching("write"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_wunprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->uw == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE UNPROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->uw) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_WUNPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to WRITE UNPROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->uw != STM32_CMD_UW_NS) - stm32_warn_stretching("WRITE UNPROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_wprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->wp == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE PROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->wp) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_WPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to WRITE PROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->wp != STM32_CMD_WP_NS) - stm32_warn_stretching("WRITE PROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_runprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->ur == STM32_CMD_ERR) { - fprintf(stderr, "Error: READOUT UNPROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->ur) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to READOUT UNPROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->ur != STM32_CMD_UR_NS) - stm32_warn_stretching("READOUT UNPROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_readprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->rp == STM32_CMD_ERR) { - fprintf(stderr, "Error: READOUT PROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->rp) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_RPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to READOUT PROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->rp != STM32_CMD_RP_NS) - stm32_warn_stretching("READOUT PROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - port_err_t p_err; - - if (!pages) - return STM32_ERR_OK; - - if (stm->cmd->er == STM32_CMD_ERR) { - fprintf(stderr, "Error: ERASE command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->er) != STM32_ERR_OK) { - fprintf(stderr, "Can't initiate chip erase!\n"); - return STM32_ERR_UNKNOWN; - } - - /* The erase command reported by the bootloader is either 0x43, 0x44 or 0x45 */ - /* 0x44 is Extended Erase, a 2 byte based protocol and needs to be handled differently. */ - /* 0x45 is clock no-stretching version of Extended Erase for I2C port. */ - if (stm->cmd->er != STM32_CMD_ER) { - /* Not all chips using Extended Erase support mass erase */ - /* Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range */ - /* So if someone has not overridden the default, but uses one of these chips, take it out of */ - /* mass erase mode, so it will be done page by page. This maximum might not be correct either! */ - if (stm->pid == 0x416 && pages == 0xFF) - pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ - - if (pages == 0xFF) { - uint8_t buf[3]; - - /* 0xFFFF the magic number for mass erase */ - buf[0] = 0xFF; - buf[1] = 0xFF; - buf[2] = 0x00; /* checksum */ - if (port->write(port, buf, 3) != PORT_ERR_OK) { - fprintf(stderr, "Mass erase error.\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Mass erase failed. Try specifying the number of pages to be erased.\n"); - if (port->flags & PORT_STRETCH_W - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } - - uint16_t pg_num; - uint8_t pg_byte; - uint8_t cs = 0; - uint8_t *buf; - int i = 0; - - buf = malloc(2 + 2 * pages + 1); - if (!buf) - return STM32_ERR_UNKNOWN; - - /* Number of pages to be erased - 1, two bytes, MSB first */ - pg_byte = (pages - 1) >> 8; - buf[i++] = pg_byte; - cs ^= pg_byte; - pg_byte = (pages - 1) & 0xFF; - buf[i++] = pg_byte; - cs ^= pg_byte; - - for (pg_num = spage; pg_num < spage + pages; pg_num++) { - pg_byte = pg_num >> 8; - cs ^= pg_byte; - buf[i++] = pg_byte; - pg_byte = pg_num & 0xFF; - cs ^= pg_byte; - buf[i++] = pg_byte; - } - buf[i++] = cs; - p_err = port->write(port, buf, i); - free(buf); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Page-by-page erase error.\n"); - return STM32_ERR_UNKNOWN; - } - - s_err = stm32_get_ack_timeout(stm, pages * STM32_SECTERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Page-by-page erase failed. Check the maximum pages your device supports.\n"); - if (port->flags & PORT_STRETCH_W - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - - return STM32_ERR_OK; - } - - /* And now the regular erase (0x43) for all other chips */ - if (pages == 0xFF) { - s_err = stm32_send_command_timeout(stm, 0xFF, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } else { - uint8_t cs = 0; - uint8_t pg_num; - uint8_t *buf; - int i = 0; - - buf = malloc(1 + pages + 1); - if (!buf) - return STM32_ERR_UNKNOWN; - - buf[i++] = pages - 1; - cs ^= (pages-1); - for (pg_num = spage; pg_num < (pages + spage); pg_num++) { - buf[i++] = pg_num; - cs ^= pg_num; - } - buf[i++] = cs; - p_err = port->write(port, buf, i); - free(buf); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Erase failed.\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } -} - -static stm32_err_t stm32_run_raw_code(const stm32_t *stm, - uint32_t target_address, - const uint8_t *code, uint32_t code_size) -{ - uint32_t stack_le = le_u32(0x20002000); - uint32_t code_address_le = le_u32(target_address + 8); - uint32_t length = code_size + 8; - uint8_t *mem, *pos; - uint32_t address, w; - - /* Must be 32-bit aligned */ - if (target_address & 0x3) { - fprintf(stderr, "Error: code address must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - mem = malloc(length); - if (!mem) - return STM32_ERR_UNKNOWN; - - memcpy(mem, &stack_le, sizeof(uint32_t)); - memcpy(mem + 4, &code_address_le, sizeof(uint32_t)); - memcpy(mem + 8, code, code_size); - - pos = mem; - address = target_address; - while (length > 0) { - w = length > 256 ? 256 : length; - if (stm32_write_memory(stm, address, pos, w) != STM32_ERR_OK) { - free(mem); - return STM32_ERR_UNKNOWN; - } - - address += w; - pos += w; - length -= w; - } - - free(mem); - return stm32_go(stm, target_address); -} - -stm32_err_t stm32_go(const stm32_t *stm, uint32_t address) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (stm->cmd->go == STM32_CMD_ERR) { - fprintf(stderr, "Error: GO command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->go) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; -} - -stm32_err_t stm32_reset_device(const stm32_t *stm) -{ - uint32_t target_address = stm->dev->ram_start; - - return stm32_run_raw_code(stm, target_address, stm_reset_code, stm_reset_code_length); -} - -stm32_err_t stm32_crc_memory(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (address & 0x3 || length & 0x3) { - fprintf(stderr, "Start and end addresses must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->crc == STM32_CMD_ERR) { - fprintf(stderr, "Error: CRC command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->crc) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = length >> 24; - buf[1] = (length >> 16) & 0xFF; - buf[2] = (length >> 8) & 0xFF; - buf[3] = length & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (port->read(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (buf[4] != (buf[0] ^ buf[1] ^ buf[2] ^ buf[3])) - return STM32_ERR_UNKNOWN; - - *crc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; - return STM32_ERR_OK; -} - -/* - * CRC computed by STM32 is similar to the standard crc32_be() - * implemented, for example, in Linux kernel in ./lib/crc32.c - * But STM32 computes it on units of 32 bits word and swaps the - * bytes of the word before the computation. - * Due to byte swap, I cannot use any CRC available in existing - * libraries, so here is a simple not optimized implementation. - */ -#define CRCPOLY_BE 0x04c11db7 -#define CRC_MSBMASK 0x80000000 -#define CRC_INIT_VALUE 0xFFFFFFFF -uint32_t stm32_sw_crc(uint32_t crc, uint8_t *buf, unsigned int len) -{ - int i; - uint32_t data; - - if (len & 0x3) { - fprintf(stderr, "Buffer length must be multiple of 4 bytes\n"); - return 0; - } - - while (len) { - data = *buf++; - data |= *buf++ << 8; - data |= *buf++ << 16; - data |= *buf++ << 24; - len -= 4; - - crc ^= data; - - for (i = 0; i < 32; i++) - if (crc & CRC_MSBMASK) - crc = (crc << 1) ^ CRCPOLY_BE; - else - crc = (crc << 1); - } - return crc; -} - -stm32_err_t stm32_crc_wrapper(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc) -{ - uint8_t buf[256]; - uint32_t start, total_len, len, current_crc; - - if (address & 0x3 || length & 0x3) { - fprintf(stderr, "Start and end addresses must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->crc != STM32_CMD_ERR) - return stm32_crc_memory(stm, address, length, crc); - - start = address; - total_len = length; - current_crc = CRC_INIT_VALUE; - while (length) { - len = length > 256 ? 256 : length; - if (stm32_read_memory(stm, address, buf, len) != STM32_ERR_OK) { - fprintf(stderr, - "Failed to read memory at address 0x%08x, target write-protected?\n", - address); - return STM32_ERR_UNKNOWN; - } - current_crc = stm32_sw_crc(current_crc, buf, len); - length -= len; - address += len; - - fprintf(stderr, - "\rCRC address 0x%08x (%.2f%%) ", - address, - (100.0f / (float)total_len) * (float)(address - start) - ); - fflush(stderr); - } - fprintf(stderr, "Done.\n"); - *crc = current_crc; - return STM32_ERR_OK; -} diff --git a/linux/src/stm32flash_serial/src/stm32.h b/linux/src/stm32flash_serial/src/stm32.h deleted file mode 100644 index 1688fcb4b..000000000 --- a/linux/src/stm32flash_serial/src/stm32.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _STM32_H -#define _STM32_H - -#include -#include "serial.h" - -#define STM32_MAX_RX_FRAME 256 /* cmd read memory */ -#define STM32_MAX_TX_FRAME (1 + 256 + 1) /* cmd write memory */ - -typedef enum { - STM32_ERR_OK = 0, - STM32_ERR_UNKNOWN, /* Generic error */ - STM32_ERR_NACK, - STM32_ERR_NO_CMD, /* Command not available in bootloader */ -} stm32_err_t; - -typedef struct stm32 stm32_t; -typedef struct stm32_cmd stm32_cmd_t; -typedef struct stm32_dev stm32_dev_t; - -struct stm32 { - const serial_t *serial; - struct port_interface *port; - uint8_t bl_version; - uint8_t version; - uint8_t option1, option2; - uint16_t pid; - stm32_cmd_t *cmd; - const stm32_dev_t *dev; -}; - -struct stm32_dev { - uint16_t id; - const char *name; - uint32_t ram_start, ram_end; - uint32_t fl_start, fl_end; - uint16_t fl_pps; // pages per sector - uint16_t fl_ps; // page size - uint32_t opt_start, opt_end; - uint32_t mem_start, mem_end; -}; - -stm32_t *stm32_init(struct port_interface *port, const char init); -void stm32_close(stm32_t *stm); -stm32_err_t stm32_read_memory(const stm32_t *stm, uint32_t address, - uint8_t data[], unsigned int len); -stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, - const uint8_t data[], unsigned int len); -stm32_err_t stm32_wunprot_memory(const stm32_t *stm); -stm32_err_t stm32_wprot_memory(const stm32_t *stm); -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, - uint8_t pages); -stm32_err_t stm32_go(const stm32_t *stm, uint32_t address); -stm32_err_t stm32_reset_device(const stm32_t *stm); -stm32_err_t stm32_readprot_memory(const stm32_t *stm); -stm32_err_t stm32_runprot_memory(const stm32_t *stm); -stm32_err_t stm32_crc_memory(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc); -stm32_err_t stm32_crc_wrapper(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc); -uint32_t stm32_sw_crc(uint32_t crc, uint8_t *buf, unsigned int len); - -#endif - diff --git a/linux/src/stm32flash_serial/src/stm32flash.1 b/linux/src/stm32flash_serial/src/stm32flash.1 deleted file mode 100644 index d37292f6a..000000000 --- a/linux/src/stm32flash_serial/src/stm32flash.1 +++ /dev/null @@ -1,407 +0,0 @@ -.TH STM32FLASH 1 "2013\-11\-03" STM32FLASH "User command" -.SH NAME -stm32flash \- flashing utility for STM32 and STM32W through UART or I2C -.SH SYNOPSIS -.B stm32flash -.RB [ \-cfhjkouvCR ] -.RB [ \-a -.IR bus_address ] -.RB [ \-b -.IR baud_rate ] -.RB [ \-m -.IR serial_mode ] -.RB [ \-r -.IR filename ] -.RB [ \-w -.IR filename ] -.RB [ \-e -.IR num ] -.RB [ \-n -.IR count ] -.RB [ \-g -.IR address ] -.RB [ \-s -.IR start_page ] -.RB [ \-S -.IR address [: length ]] -.RB [ \-F -.IR RX_length [: TX_length ]] -.RB [ \-i -.IR GPIO_string ] -.RI [ tty_device -.R | -.IR i2c_device ] - -.SH DESCRIPTION -.B stm32flash -reads or writes the flash memory of STM32 and STM32W. - -It requires the STM32[W] to embed a bootloader compliant with ST -application note AN3155. -.B stm32flash -uses the serial port -.I tty_device -to interact with the bootloader of STM32[W]. - -.SH OPTIONS -.TP -.BI "\-a" " bus_address" -Specify address on bus for -.IR i2c_device . -This option is mandatory for I2C interface. - -.TP -.BI "\-b" " baud_rate" -Specify baud rate speed of -.IR tty_device . -Please notice that the ST bootloader can automatically detect the baud rate, -as explaned in chapter 2 of AN3155. -This option could be required together with option -.B "\-c" -or if following interaction with bootloader is expected. -Default is -.IR 57600 . - -.TP -.BI "\-m" " mode" -Specify the format of UART data. -.I mode -is a three characters long string where each character specifies, in -this strict order, character size, parity and stop bits. -The only values currenly used are -.I 8e1 -for standard STM32 bootloader and -.I 8n1 -for standard STM32W bootloader. -Default is -.IR 8e1 . - -.TP -.BI "\-r" " filename" -Specify to read the STM32[W] flash and write its content in -.I filename -in raw binary format (see below -.BR "FORMAT CONVERSION" ). - -.TP -.BI "\-w" " filename" -Specify to write the STM32[W] flash with the content of -.IR filename . -File format can be either raw binary or intel hex (see below -.BR "FORMAT CONVERSION" ). -The file format is automatically detected. -To by\-pass format detection and force binary mode (e.g. to -write an intel hex content in STM32[W] flash), use -.B \-f -option. - -.TP -.B \-u -Specify to disable write\-protection from STM32[W] flash. -The STM32[W] will be reset after this operation. - -.TP -.B \-j -Enable the flash read\-protection. - -.TP -.B \-k -Disable the flash read\-protection. - -.TP -.B \-o -Erase only. - -.TP -.BI "\-e" " num" -Specify to erase only -.I num -pages before writing the flash. Default is to erase the whole flash. With -.B \-e 0 -the flash would not be erased. - -.TP -.B \-v -Specify to verify flash content after write operation. - -.TP -.BI "\-n" " count" -Specify to retry failed writes up to -.I count -times. Default is 10 times. - -.TP -.BI "\-g" " address" -Specify address to start execution from (0 = flash start). - -.TP -.BI "\-s" " start_page" -Specify flash page offset (0 = flash start). - -.TP -.BI "\-S" " address" "[:" "length" "]" -Specify start address and optionally length for read/write/erase/crc operations. - -.TP -.BI "\-F" " RX_length" "[:" "TX_length" "]" -Specify the maximum frame size for the current interface. -Due to STM32 bootloader protocol, host will never handle frames bigger than -256 byte in RX or 258 byte in TX. -Due to current code, lowest limit in RX is 20 byte (to read a complete reply -of command GET). Minimum limit in TX is 5 byte, required by protocol. - -.TP -.B \-f -Force binary parser while reading file with -.BR "\-w" "." - -.TP -.B \-h -Show help. - -.TP -.B \-c -Specify to resume the existing UART connection and don't send initial -INIT sequence to detect baud rate. Baud rate must be kept the same as the -existing connection. This is useful if the reset fails. - -.TP -.BI "\-i" " GPIO_string" -Specify the GPIO sequences on the host to force STM32[W] to enter and -exit bootloader mode. GPIO can either be real GPIO connected from host to -STM32[W] beside the UART connection, or UART's modem signals used as -GPIO. (See below -.B BOOTLOADER GPIO SEQUENCE -for the format of -.I GPIO_string -and further explanation). - -.TP -.B \-C -Specify to compute CRC on memory content. -By default the CRC is computed on the whole flash content. -Use -.B "\-S" -to provide different memory address range. - -.TP -.B \-R -Specify to reset the device at exit. -This option is ignored if either -.BR "\-g" "," -.BR "\-j" "," -.B "\-k" -or -.B "\-u" -is also specified. - -.SH BOOTLOADER GPIO SEQUENCE -This feature is currently available on Linux host only. - -As explained in ST application note AN2606, after reset the STM32 will -execute either the application program in user flash or the bootloader, -depending on the level applied at specific pins of STM32 during reset. - -STM32 bootloader is automatically activated by configuring the pins -BOOT0="high" and BOOT1="low" and then by applying a reset. -Application program in user flash is activated by configuring the pin -BOOT0="low" (the level on BOOT1 is ignored) and then by applying a reset. - -When GPIO from host computer are connected to either configuration and -reset pins of STM32, -.B stm32flash -can control the host GPIO to reset STM32 and to force execution of -bootloader or execution of application program. - -The sequence of GPIO values to entry to and exit from bootloader mode is -provided with command line option -.B "\-i" -.IR "GPIO_string" . - -.PD 0 -The format of -.IR "GPIO_string" " is:" -.RS -GPIO_string = [entry sequence][:[exit sequence]] -.P -sequence = [\-]n[,sequence] -.RE -.P -In the above sequences, negative numbers correspond to GPIO at "low" level; -numbers without sign correspond to GPIO at "high" level. -The value "n" can either be the GPIO number on the host system or the -string "rts", "dtr" or "brk". The strings "rts" and "dtr" drive the -corresponding UART's modem lines RTS and DTR as GPIO. -The string "brk" forces the UART to send a BREAK sequence on TX line; -after BREAK the UART is returned in normal "non\-break" mode. -Note: the string "\-brk" has no effect and is ignored. -.PD - -.PD 0 -As example, let's suppose the following connection between host and STM32: -.IP \(bu 2 -host GPIO_3 connected to reset pin of STM32; -.IP \(bu 2 -host GPIO_4 connected to STM32 pin BOOT0; -.IP \(bu 2 -host GPIO_5 connected to STM32 pin BOOT1. -.PD -.P - -In this case, the sequence to enter in bootloader mode is: first put -GPIO_4="high" and GPIO_5="low"; then send reset pulse by GPIO_3="low" -followed by GPIO_3="high". -The corresponding string for -.I GPIO_string -is "4,\-5,\-3,3". - -To exit from bootloade and run the application program, the sequence is: -put GPIO_4="low"; then send reset pulse. -The corresponding string for -.I GPIO_string -is "\-4,\-3,3". - -The complete command line flag is "\-i 4,\-5,\-3,3:\-4,\-3,3". - -STM32W uses pad PA5 to select boot mode; if during reset PA5 is "low" then -STM32W will enter in bootloader mode; if PA5 is "high" it will execute the -program in flash. - -As example, supposing GPIO_3 connected to PA5 and GPIO_2 to STM32W's reset. -The command: -.PD 0 -.RS -stm32flash \-i \-3,\-2,2:3,\-2,2 /dev/ttyS0 -.RE -provides: -.IP \(bu 2 -entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high -.IP \(bu 2 -exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high -.PD - -.SH EXAMPLES -Get device information: -.RS -.PD 0 -.P -stm32flash /dev/ttyS0 -.PD -.RE - -Write with verify and then start execution: -.RS -.PD 0 -.P -stm32flash \-w filename \-v \-g 0x0 /dev/ttyS0 -.PD -.RE - -Read flash to file: -.RS -.PD 0 -.P -stm32flash \-r filename /dev/ttyS0 -.PD -.RE - -Start execution: -.RS -.PD 0 -.P -stm32flash \-g 0x0 /dev/ttyS0 -.PD -.RE - -Specify: -.PD 0 -.IP \(bu 2 -entry sequence: RTS=low, DTR=low, DTR=high -.IP \(bu 2 -exit sequence: RTS=high, DTR=low, DTR=high -.P -.RS -stm32flash \-i \-rts,\-dtr,dtr:rts,\-dtr,dtr /dev/ttyS0 -.PD -.RE - -.SH FORMAT CONVERSION -Flash images provided by ST or created with ST tools are often in file -format Motorola S\-Record. -Conversion between raw binary, intel hex and Motorola S\-Record can be -done through software package SRecord. - -.SH AUTHORS -The original software package -.B stm32flash -is written by -.I Geoffrey McRae -and is since 2012 maintained by -.IR "Tormod Volden " . - -Man page and extension to STM32W and I2C are written by -.IR "Antonio Borneo " . - -Please report any bugs at the project homepage -http://stm32flash.googlecode.com . - -.SH SEE ALSO -.BR "srec_cat" "(1)," " srec_intel" "(5)," " srec_motorola" "(5)." - -The communication protocol used by ST bootloader is documented in -following ST application notes, depending on communication port. -The current version of -.B stm32flash -only supports -.I UART -and -.I I2C -ports. -.PD 0 -.P -.IP \(bu 2 -AN3154: CAN protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/CD00264321.pdf -.RE - -.P -.IP \(bu 2 -AN3155: USART protocol used in the STM32(TM) bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/CD00264342.pdf -.RE - -.P -.IP \(bu 2 -AN4221: I2C protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/DM00072315.pdf -.RE - -.P -.IP \(bu 2 -AN4286: SPI protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/DM00081379.pdf -.RE - -.PD - - -Boot mode selection for STM32 is documented in ST application note -AN2606, available from the ST website: -.PD 0 -.P -http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf -.PD - -.SH LICENSE -.B stm32flash -is distributed under GNU GENERAL PUBLIC LICENSE Version 2. -Copy of the license is available within the source code in the file -.IR "gpl\-2.0.txt" . diff --git a/linux/src/stm32flash_serial/src/utils.c b/linux/src/stm32flash_serial/src/utils.c deleted file mode 100644 index 271bb3ed7..000000000 --- a/linux/src/stm32flash_serial/src/utils.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include "utils.h" - -/* detect CPU endian */ -char cpu_le() { - const uint32_t cpu_le_test = 0x12345678; - return ((const unsigned char*)&cpu_le_test)[0] == 0x78; -} - -uint32_t be_u32(const uint32_t v) { - if (cpu_le()) - return ((v & 0xFF000000) >> 24) | - ((v & 0x00FF0000) >> 8) | - ((v & 0x0000FF00) << 8) | - ((v & 0x000000FF) << 24); - return v; -} - -uint32_t le_u32(const uint32_t v) { - if (!cpu_le()) - return ((v & 0xFF000000) >> 24) | - ((v & 0x00FF0000) >> 8) | - ((v & 0x0000FF00) << 8) | - ((v & 0x000000FF) << 24); - return v; -} diff --git a/linux/src/stm32flash_serial/src/utils.h b/linux/src/stm32flash_serial/src/utils.h deleted file mode 100644 index a8d37d2d5..000000000 --- a/linux/src/stm32flash_serial/src/utils.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_UTILS -#define _H_UTILS - -#include - -char cpu_le(); -uint32_t be_u32(const uint32_t v); -uint32_t le_u32(const uint32_t v); - -#endif diff --git a/linux/stm32flash/stm32flash b/linux/stm32flash/stm32flash index 16872bba6..21abb6e38 100755 Binary files a/linux/stm32flash/stm32flash and b/linux/stm32flash/stm32flash differ diff --git a/linux64/src/stm32flash_serial/src/AUTHORS b/linux64/src/stm32flash_serial/src/AUTHORS deleted file mode 100644 index d096f2205..000000000 --- a/linux64/src/stm32flash_serial/src/AUTHORS +++ /dev/null @@ -1,19 +0,0 @@ -Authors ordered by first contribution. - -Geoffrey McRae -Bret Olmsted -Tormod Volden -Jakob Malm -Reuben Dowle -Matthias Kubisch -Paul Fertser -Daniel Strnad -Jérémie Rapin -Christian Pointner -Mats Erik Andersson -Alexey Borovik -Antonio Borneo -Armin van der Togt -Brian Silverman -Georg Hofmann -Luis Rodrigues diff --git a/linux64/src/stm32flash_serial/src/Android.mk b/linux64/src/stm32flash_serial/src/Android.mk deleted file mode 100644 index 7be3d0018..000000000 --- a/linux64/src/stm32flash_serial/src/Android.mk +++ /dev/null @@ -1,20 +0,0 @@ -TOP_LOCAL_PATH := $(call my-dir) - -include $(call all-named-subdir-makefiles, parsers) - -LOCAL_PATH := $(TOP_LOCAL_PATH) - -include $(CLEAR_VARS) -LOCAL_MODULE := stm32flash -LOCAL_SRC_FILES := \ - dev_table.c \ - i2c.c \ - init.c \ - main.c \ - port.c \ - serial_common.c \ - serial_platform.c \ - stm32.c \ - utils.c -LOCAL_STATIC_LIBRARIES := libparsers -include $(BUILD_EXECUTABLE) diff --git a/linux64/src/stm32flash_serial/src/HOWTO b/linux64/src/stm32flash_serial/src/HOWTO deleted file mode 100644 index d8f32eb04..000000000 --- a/linux64/src/stm32flash_serial/src/HOWTO +++ /dev/null @@ -1,35 +0,0 @@ -Add new interfaces: -===================================================================== -Current version 0.4 supports the following interfaces: -- UART Windows (either "COMn" and "\\.\COMn"); -- UART posix/Linux (e.g. "/dev/ttyUSB0"); -- I2C Linux through standard driver "i2c-dev" (e.g. "/dev/i2c-n"). - -Starting from version 0.4, the back-end of stm32flash is modular and -ready to be expanded to support new interfaces. -I'm planning adding SPI on Linux through standard driver "spidev". -You are invited to contribute with more interfaces. - -To add a new interface you need to add a new file, populate the struct -port_interface (check at the end of files i2c.c, serial_posix.c and -serial_w32.c) and provide the relative functions to operate on the -interface: open/close, read/write, get_cfg_str and the optional gpio. -The include the new drive in Makefile and register the new struct -port_interface in file port.c in struct port_interface *ports[]. - -There are several USB-I2C adapter in the market, each providing its -own libraries to communicate with the I2C bus. -Could be interesting to provide as back-end a bridge between stm32flash -and such libraries (I have no plan on this item). - - -Add new STM32 devices: -===================================================================== -Add a new line in file dev_table.c, in table devices[]. -The fields of the table are listed in stm32.h, struct stm32_dev. - - -Cross compile on Linux host for Windows target with MinGW: -===================================================================== -I'm using a 64 bit Arch Linux machines, and I usually run: - make CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar diff --git a/linux64/src/stm32flash_serial/src/I2C.txt b/linux64/src/stm32flash_serial/src/I2C.txt deleted file mode 100644 index 4c05ff62d..000000000 --- a/linux64/src/stm32flash_serial/src/I2C.txt +++ /dev/null @@ -1,94 +0,0 @@ -About I2C back-end communication in stm32flash -========================================================================== - -Starting from version v0.4, beside the serial communication port, -stm32flash adds support for I2C port to talk with STM32 bootloader. - -The current I2C back-end supports only the API provided by Linux kernel -driver "i2c-dev", so only I2C controllers with Linux kernel driver can be -used. -In Linux source code, most of the drivers for I2C and SMBUS controllers -are in - ./drivers/i2c/busses/ -Only I2C is supported by STM32 bootloader, so check the section below -about SMBUS. -No I2C support for Windows is available in stm32flash v0.4. - -Thanks to the new modular back-end, stm32flash can be easily extended to -support new back-ends and API. Check HOWTO file in stm32flash source code -for details. - -In the market there are several USB-to-I2C dongles; most of them are not -supported by kernel drivers. Manufacturer provide proprietary userspace -libraries using not standardized API. -These API and dongles could be supported in feature versions. - -There are currently 3 versions of STM32 bootloader for I2C communications: -- v1.0 using I2C clock stretching synchronization between host and STM32; -- v1.1 superset of v1.0, adds non stretching commands; -- v1.2 superset of v1.1, adds CRC command and compatibility with i2cdetect. -Details in ST application note AN2606. -All the bootloaders above are tested and working with stm32flash. - - -SMBUS controllers -========================================================================== - -Almost 50% of the drivers in Linux source code folder - ./drivers/i2c/busses/ -are for controllers that "only" support SMBUS protocol. They can NOT -operate with STM32 bootloader. -To identify if your controller supports I2C, use command: - i2cdetect -F n -where "n" is the number of the I2C interface (e.g. n=3 for "/dev/i2c-3"). -Controllers that supports I2C will report - I2C yes -Controller that support both I2C and SMBUS are ok. - -If you are interested on details about SMBUS protocol, you can download -the current specs from - http://smbus.org/specs/smbus20.pdf -and you can read the files in Linux source code - ./Documentation/i2c/i2c-protocol - ./Documentation/i2c/smbus-protocol - - -About bootloader v1.0 -========================================================================== - -Version v1.0 can have issues with some I2C controllers due to use of clock -stretching during commands that require long operations, like flash erase -and programming. - -Clock stretching is a technique to synchronize host and I2C device. When -I2C device wants to force a delay in the communication, it push "low" the -I2C clock; the I2C controller detects it and waits until I2C clock returns -"high". -Most I2C controllers set a "timeout" for clock stretching, ranging from -few milli-seconds to seconds depending on specific HW or SW driver. - -It is possible that the timeout in your I2C controller is smaller than the -delay required for flash erase or programming. In this case the I2C -controller will timeout and report error to stm32flash. -There is no possibility for stm32flash to retry, so it can only signal the -error and exit. - -To by-pass the issue with bootloader v1.0 you can modify the kernel driver -of your I2C controller. Not an easy job, since every controller has its own -way to handle the timeout. - -In my case I'm using the I2C controller integrated in the VGA port of my -laptop HP EliteBook 8460p. I built the 0.25$ VGA-to-I2C adapter reported in - http://www.paintyourdragon.com/?p=43 -To change the timeout of the I2C controller I had to modify the kernel file - drivers/gpu/drm/radeon/radeon_i2c.c -line 969 -- i2c->bit.timeout = usecs_to_jiffies(2200); /* from VESA */ -+ i2c->bit.timeout = msecs_to_jiffies(5000); /* 5s for STM32 */ -and recompile it. -Then - $> modprobe i2c-dev - $> chmod 666 /dev/i2c-7 - #> stm32flash -a 0x39 /dev/i2c-7 - -2014-09-16 Antonio Borneo diff --git a/linux64/src/stm32flash_serial/src/Makefile b/linux64/src/stm32flash_serial/src/Makefile deleted file mode 100644 index 0328d5588..000000000 --- a/linux64/src/stm32flash_serial/src/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -PREFIX = /usr/local -CFLAGS += -Wall -g - -INSTALL = install - -OBJS = dev_table.o \ - i2c.o \ - init.o \ - main.o \ - port.o \ - serial_common.o \ - serial_platform.o \ - stm32.o \ - utils.o - -LIBOBJS = parsers/parsers.a - -all: stm32flash - -serial_platform.o: serial_posix.c serial_w32.c - -parsers/parsers.a: - cd parsers && $(MAKE) parsers.a - -stm32flash: $(OBJS) $(LIBOBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBOBJS) - -clean: - rm -f $(OBJS) stm32flash - cd parsers && $(MAKE) $@ - -install: all - $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin - $(INSTALL) -m 755 stm32flash $(DESTDIR)$(PREFIX)/bin - $(INSTALL) -d $(DESTDIR)$(PREFIX)/share/man/man1 - $(INSTALL) -m 644 stm32flash.1 $(DESTDIR)$(PREFIX)/share/man/man1 - -.PHONY: all clean install diff --git a/linux64/src/stm32flash_serial/src/TODO b/linux64/src/stm32flash_serial/src/TODO deleted file mode 100644 index 41df614ff..000000000 --- a/linux64/src/stm32flash_serial/src/TODO +++ /dev/null @@ -1,7 +0,0 @@ - -stm32: -- Add support for variable page size - -AUTHORS: -- Add contributors from Geoffrey's commits - diff --git a/linux64/src/stm32flash_serial/src/dev_table.c b/linux64/src/stm32flash_serial/src/dev_table.c deleted file mode 100644 index 399cd9d08..000000000 --- a/linux64/src/stm32flash_serial/src/dev_table.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "stm32.h" - -/* - * Device table, corresponds to the "Bootloader device-dependant parameters" - * table in ST document AN2606. - * Note that the option bytes upper range is inclusive! - */ -const stm32_dev_t devices[] = { - /* F0 */ - {0x440, "STM32F051xx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, - {0x444, "STM32F030/F031" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, - {0x445, "STM32F042xx" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, - {0x448, "STM32F072xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, - /* F1 */ - {0x412, "Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x410, "Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x414, "High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x420, "Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x428, "High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x418, "Connectivity line" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, - {0x430, "XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, - /* Note that F2 and F4 devices have sectors of different page sizes - and only the first sectors (of one page size) are included here */ - /* F2 */ - {0x411, "STM32F2xx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, - /* F3 */ - {0x432, "STM32F373/8" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x422, "F302xB/303xB/358" , 0x20001400, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x439, "STM32F302x4(6/8)" , 0x20001800, 0x20004000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x438, "F303x4/334/328" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - /* F4 */ - {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, - /* 0x419 is also used for STM32F429/39 but with other bootloader ID... */ - {0x419, "STM32F427/37" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - /* L0 */ - {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - /* L1 */ - {0x416, "L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x429, "L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x427, "L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, - {0x436, "L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - {0x437, "L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - /* These are not (yet) in AN2606: */ - {0x641, "Medium_Density PL" , 0x20000200, 0x00005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, - {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 1, 2048, 0, 0, 0, 0}, - {0x0} -}; diff --git a/linux64/src/stm32flash_serial/src/gpl-2.0.txt b/linux64/src/stm32flash_serial/src/gpl-2.0.txt deleted file mode 100644 index d159169d1..000000000 --- a/linux64/src/stm32flash_serial/src/gpl-2.0.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/linux64/src/stm32flash_serial/src/i2c.c b/linux64/src/stm32flash_serial/src/i2c.c deleted file mode 100644 index 10e6bb15a..000000000 --- a/linux64/src/stm32flash_serial/src/i2c.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - - -#if !defined(__linux__) - -static port_err_t i2c_open(struct port_interface *port, - struct port_options *ops) -{ - return PORT_ERR_NODEV; -} - -struct port_interface port_i2c = { - .name = "i2c", - .open = i2c_open, -}; - -#else - -#ifdef __ANDROID__ -#define I2C_SLAVE 0x0703 /* Use this slave address */ -#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */ -/* To determine what functionality is present */ -#define I2C_FUNC_I2C 0x00000001 -#else -#include -#include -#endif - -#include - -struct i2c_priv { - int fd; - int addr; -}; - -static port_err_t i2c_open(struct port_interface *port, - struct port_options *ops) -{ - struct i2c_priv *h; - int fd, addr, ret; - unsigned long funcs; - - /* 1. check device name match */ - if (strncmp(ops->device, "/dev/i2c-", strlen("/dev/i2c-"))) - return PORT_ERR_NODEV; - - /* 2. check options */ - addr = ops->bus_addr; - if (addr < 0x03 || addr > 0x77) { - fprintf(stderr, "I2C address out of range [0x03-0x77]\n"); - return PORT_ERR_UNKNOWN; - } - - /* 3. open it */ - h = calloc(sizeof(*h), 1); - if (h == NULL) { - fprintf(stderr, "End of memory\n"); - return PORT_ERR_UNKNOWN; - } - fd = open(ops->device, O_RDWR); - if (fd < 0) { - fprintf(stderr, "Unable to open special file \"%s\"\n", - ops->device); - free(h); - return PORT_ERR_UNKNOWN; - } - - /* 3.5. Check capabilities */ - ret = ioctl(fd, I2C_FUNCS, &funcs); - if (ret < 0) { - fprintf(stderr, "I2C ioctl(funcs) error %d\n", errno); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - if ((funcs & I2C_FUNC_I2C) == 0) { - fprintf(stderr, "Error: controller is not I2C, only SMBUS.\n"); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - - /* 4. set options */ - ret = ioctl(fd, I2C_SLAVE, addr); - if (ret < 0) { - fprintf(stderr, "I2C ioctl(slave) error %d\n", errno); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - - h->fd = fd; - h->addr = addr; - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t i2c_close(struct port_interface *port) -{ - struct i2c_priv *h; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - close(h->fd); - free(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t i2c_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - struct i2c_priv *h; - int ret; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - ret = read(h->fd, buf, nbyte); - if (ret != nbyte) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; -} - -static port_err_t i2c_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - struct i2c_priv *h; - int ret; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - ret = write(h->fd, buf, nbyte); - if (ret != nbyte) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; -} - -static port_err_t i2c_gpio(struct port_interface *port, serial_gpio_t n, - int level) -{ - return PORT_ERR_OK; -} - -static const char *i2c_get_cfg_str(struct port_interface *port) -{ - struct i2c_priv *h; - static char str[11]; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return "INVALID"; - snprintf(str, sizeof(str), "addr 0x%2x", h->addr); - return str; -} - -static struct varlen_cmd i2c_cmd_get_reply[] = { - {0x10, 11}, - {0x11, 17}, - {0x12, 18}, - { /* sentinel */ } -}; - -struct port_interface port_i2c = { - .name = "i2c", - .flags = PORT_STRETCH_W, - .open = i2c_open, - .close = i2c_close, - .read = i2c_read, - .write = i2c_write, - .gpio = i2c_gpio, - .cmd_get_reply = i2c_cmd_get_reply, - .get_cfg_str = i2c_get_cfg_str, -}; - -#endif diff --git a/linux64/src/stm32flash_serial/src/init.c b/linux64/src/stm32flash_serial/src/init.c deleted file mode 100644 index 77a571bd8..000000000 --- a/linux64/src/stm32flash_serial/src/init.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include "init.h" -#include "serial.h" -#include "stm32.h" -#include "port.h" - -struct gpio_list { - struct gpio_list *next; - int gpio; -}; - - -static int write_to(const char *filename, const char *value) -{ - int fd, ret; - - fd = open(filename, O_WRONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open file \"%s\"\n", filename); - return 0; - } - ret = write(fd, value, strlen(value)); - if (ret < 0) { - fprintf(stderr, "Error writing in file \"%s\"\n", filename); - close(fd); - return 0; - } - close(fd); - return 1; -} - -#if !defined(__linux__) -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) -{ - fprintf(stderr, "GPIO control only available in Linux\n"); - return 0; -} -#else -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) -{ - char num[16]; /* sized to carry MAX_INT */ - char file[48]; /* sized to carry longest filename */ - struct stat buf; - struct gpio_list *new; - int ret; - - sprintf(file, "/sys/class/gpio/gpio%d/direction", n); - ret = stat(file, &buf); - if (ret) { - /* file miss, GPIO not exported yet */ - sprintf(num, "%d", n); - ret = write_to("/sys/class/gpio/export", num); - if (!ret) - return 0; - ret = stat(file, &buf); - if (ret) { - fprintf(stderr, "GPIO %d not available\n", n); - return 0; - } - new = (struct gpio_list *)malloc(sizeof(struct gpio_list)); - if (new == NULL) { - fprintf(stderr, "Out of memory\n"); - return 0; - } - new->gpio = n; - new->next = *gpio_to_release; - *gpio_to_release = new; - } - - return write_to(file, level ? "high" : "low"); -} -#endif - -static int release_gpio(int n) -{ - char num[16]; /* sized to carry MAX_INT */ - - sprintf(num, "%d", n); - return write_to("/sys/class/gpio/unexport", num); -} - -static int gpio_sequence(struct port_interface *port, const char *s, size_t l) -{ - struct gpio_list *gpio_to_release = NULL, *to_free; - int ret, level, gpio; - - ret = 1; - while (ret == 1 && *s && l > 0) { - if (*s == '-') { - level = 0; - s++; - l--; - } else - level = 1; - - if (isdigit(*s)) { - gpio = atoi(s); - while (isdigit(*s)) { - s++; - l--; - } - } else if (!strncmp(s, "rts", 3)) { - gpio = -GPIO_RTS; - s += 3; - l -= 3; - } else if (!strncmp(s, "dtr", 3)) { - gpio = -GPIO_DTR; - s += 3; - l -= 3; - } else if (!strncmp(s, "brk", 3)) { - gpio = -GPIO_BRK; - s += 3; - l -= 3; - } else { - fprintf(stderr, "Character \'%c\' is not a digit\n", *s); - ret = 0; - break; - } - - if (*s && (l > 0)) { - if (*s == ',') { - s++; - l--; - } else { - fprintf(stderr, "Character \'%c\' is not a separator\n", *s); - ret = 0; - break; - } - } - if (gpio < 0) - ret = (port->gpio(port, -gpio, level) == PORT_ERR_OK); - else - ret = drive_gpio(gpio, level, &gpio_to_release); - usleep(100000); - } - - while (gpio_to_release) { - release_gpio(gpio_to_release->gpio); - to_free = gpio_to_release; - gpio_to_release = gpio_to_release->next; - free(to_free); - } - usleep(500000); - return ret; -} - -static int gpio_bl_entry(struct port_interface *port, const char *seq) -{ - char *s; - - if (seq == NULL || seq[0] == ':') - return 1; - - s = strchr(seq, ':'); - if (s == NULL) - return gpio_sequence(port, seq, strlen(seq)); - - return gpio_sequence(port, seq, s - seq); -} - -static int gpio_bl_exit(struct port_interface *port, const char *seq) -{ - char *s; - - if (seq == NULL) - return 1; - - s = strchr(seq, ':'); - if (s == NULL || s[1] == '\0') - return 1; - - return gpio_sequence(port, s + 1, strlen(s + 1)); -} - -int init_bl_entry(struct port_interface *port, const char *seq) -{ - if (seq) - return gpio_bl_entry(port, seq); - - return 1; -} - -int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq) -{ - if (seq) - return gpio_bl_exit(port, seq); - - if (stm32_reset_device(stm) != STM32_ERR_OK) - return 0; - return 1; -} diff --git a/linux64/src/stm32flash_serial/src/init.h b/linux64/src/stm32flash_serial/src/init.h deleted file mode 100644 index 6075b519b..000000000 --- a/linux64/src/stm32flash_serial/src/init.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _INIT_H -#define _INIT_H - -#include "stm32.h" -#include "port.h" - -int init_bl_entry(struct port_interface *port, const char *seq); -int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq); - -#endif diff --git a/linux64/src/stm32flash_serial/src/main.c b/linux64/src/stm32flash_serial/src/main.c deleted file mode 100644 index f081d6131..000000000 --- a/linux64/src/stm32flash_serial/src/main.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright 2010 Geoffrey McRae - Copyright 2011 Steve Markgraf - Copyright 2012 Tormod Volden - Copyright 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "init.h" -#include "utils.h" -#include "serial.h" -#include "stm32.h" -#include "parsers/parser.h" -#include "port.h" - -#include "parsers/binary.h" -#include "parsers/hex.h" - -#define VERSION "Arduino_STM32_0.9" - -/* device globals */ -stm32_t *stm = NULL; - -void *p_st = NULL; -parser_t *parser = NULL; - -/* settings */ -struct port_options port_opts = { - .device = NULL, - .baudRate = SERIAL_BAUD_57600, - .serial_mode = "8e1", - .bus_addr = 0, - .rx_frame_max = STM32_MAX_RX_FRAME, - .tx_frame_max = STM32_MAX_TX_FRAME, -}; -int rd = 0; -int wr = 0; -int wu = 0; -int rp = 0; -int ur = 0; -int eraseOnly = 0; -int crc = 0; -int npages = 0; -int spage = 0; -int no_erase = 0; -char verify = 0; -int retry = 10; -char exec_flag = 0; -uint32_t execute = 0; -char init_flag = 1; -char force_binary = 0; -char reset_flag = 0; -char *filename; -char *gpio_seq = NULL; -uint32_t start_addr = 0; -uint32_t readwrite_len = 0; - -/* functions */ -int parse_options(int argc, char *argv[]); -void show_help(char *name); - -static int is_addr_in_ram(uint32_t addr) -{ - return addr >= stm->dev->ram_start && addr < stm->dev->ram_end; -} - -static int is_addr_in_flash(uint32_t addr) -{ - return addr >= stm->dev->fl_start && addr < stm->dev->fl_end; -} - -static int flash_addr_to_page_floor(uint32_t addr) -{ - if (!is_addr_in_flash(addr)) - return 0; - - return (addr - stm->dev->fl_start) / stm->dev->fl_ps; -} - -static int flash_addr_to_page_ceil(uint32_t addr) -{ - if (!(addr >= stm->dev->fl_start && addr <= stm->dev->fl_end)) - return 0; - - return (addr + stm->dev->fl_ps - 1 - stm->dev->fl_start) - / stm->dev->fl_ps; -} - -static uint32_t flash_page_to_addr(int page) -{ - return stm->dev->fl_start + page * stm->dev->fl_ps; -} - -int main(int argc, char* argv[]) { - struct port_interface *port = NULL; - int ret = 1; - stm32_err_t s_err; - parser_err_t perr; - FILE *diag = stdout; - - fprintf(diag, "stm32flash " VERSION "\n\n"); - fprintf(diag, "http://github.com/rogerclarkmelbourne/arduino_stm32\n\n"); - if (parse_options(argc, argv) != 0) - goto close; - - if (rd && filename[0] == '-') { - diag = stderr; - } - - if (wr) { - /* first try hex */ - if (!force_binary) { - parser = &PARSER_HEX; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - } - - if (force_binary || (perr = parser->open(p_st, filename, 0)) != PARSER_ERR_OK) { - if (force_binary || perr == PARSER_ERR_INVALID_FILE) { - if (!force_binary) { - parser->close(p_st); - p_st = NULL; - } - - /* now try binary */ - parser = &PARSER_BINARY; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - perr = parser->open(p_st, filename, 0); - } - - /* if still have an error, fail */ - if (perr != PARSER_ERR_OK) { - fprintf(stderr, "%s ERROR: %s\n", parser->name, parser_errstr(perr)); - if (perr == PARSER_ERR_SYSTEM) perror(filename); - goto close; - } - } - - fprintf(diag, "Using Parser : %s\n", parser->name); - } else { - parser = &PARSER_BINARY; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - } - - if (port_open(&port_opts, &port) != PORT_ERR_OK) { - fprintf(stderr, "Failed to open port: %s\n", port_opts.device); - goto close; - } - - fprintf(diag, "Interface %s: %s\n", port->name, port->get_cfg_str(port)); - if (init_flag && init_bl_entry(port, gpio_seq) == 0) - goto close; - stm = stm32_init(port, init_flag); - if (!stm) - goto close; - - fprintf(diag, "Version : 0x%02x\n", stm->bl_version); - if (port->flags & PORT_GVR_ETX) { - fprintf(diag, "Option 1 : 0x%02x\n", stm->option1); - fprintf(diag, "Option 2 : 0x%02x\n", stm->option2); - } - fprintf(diag, "Device ID : 0x%04x (%s)\n", stm->pid, stm->dev->name); - fprintf(diag, "- RAM : %dKiB (%db reserved by bootloader)\n", (stm->dev->ram_end - 0x20000000) / 1024, stm->dev->ram_start - 0x20000000); - fprintf(diag, "- Flash : %dKiB (sector size: %dx%d)\n", (stm->dev->fl_end - stm->dev->fl_start ) / 1024, stm->dev->fl_pps, stm->dev->fl_ps); - fprintf(diag, "- Option RAM : %db\n", stm->dev->opt_end - stm->dev->opt_start + 1); - fprintf(diag, "- System RAM : %dKiB\n", (stm->dev->mem_end - stm->dev->mem_start) / 1024); - - uint8_t buffer[256]; - uint32_t addr, start, end; - unsigned int len; - int failed = 0; - int first_page, num_pages; - - /* - * Cleanup addresses: - * - * Starting from options - * start_addr, readwrite_len, spage, npages - * and using device memory size, compute - * start, end, first_page, num_pages - */ - if (start_addr || readwrite_len) { - start = start_addr; - - if (is_addr_in_flash(start)) - end = stm->dev->fl_end; - else { - no_erase = 1; - if (is_addr_in_ram(start)) - end = stm->dev->ram_end; - else - end = start + sizeof(uint32_t); - } - - if (readwrite_len && (end > start + readwrite_len)) - end = start + readwrite_len; - - first_page = flash_addr_to_page_floor(start); - if (!first_page && end == stm->dev->fl_end) - num_pages = 0xff; /* mass erase */ - else - num_pages = flash_addr_to_page_ceil(end) - first_page; - } else if (!spage && !npages) { - start = stm->dev->fl_start; - end = stm->dev->fl_end; - first_page = 0; - num_pages = 0xff; /* mass erase */ - } else { - first_page = spage; - start = flash_page_to_addr(first_page); - if (start > stm->dev->fl_end) { - fprintf(stderr, "Address range exceeds flash size.\n"); - goto close; - } - - if (npages) { - num_pages = npages; - end = flash_page_to_addr(first_page + num_pages); - if (end > stm->dev->fl_end) - end = stm->dev->fl_end; - } else { - end = stm->dev->fl_end; - num_pages = flash_addr_to_page_ceil(end) - first_page; - } - - if (!first_page && end == stm->dev->fl_end) - num_pages = 0xff; /* mass erase */ - } - - if (rd) { - unsigned int max_len = port_opts.rx_frame_max; - - fprintf(diag, "Memory read\n"); - - perr = parser->open(p_st, filename, 1); - if (perr != PARSER_ERR_OK) { - fprintf(stderr, "%s ERROR: %s\n", parser->name, parser_errstr(perr)); - if (perr == PARSER_ERR_SYSTEM) - perror(filename); - goto close; - } - - fflush(diag); - addr = start; - while(addr < end) { - uint32_t left = end - addr; - len = max_len > left ? left : max_len; - s_err = stm32_read_memory(stm, addr, buffer, len); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read memory at address 0x%08x, target write-protected?\n", addr); - goto close; - } - if (parser->write(p_st, buffer, len) != PARSER_ERR_OK) - { - fprintf(stderr, "Failed to write data to file\n"); - goto close; - } - addr += len; - - fprintf(diag, - "\rRead address 0x%08x (%.2f%%) ", - addr, - (100.0f / (float)(end - start)) * (float)(addr - start) - ); - fflush(diag); - } - fprintf(diag, "Done.\n"); - ret = 0; - goto close; - } else if (rp) { - fprintf(stdout, "Read-Protecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_readprot_memory(stm); - fprintf(stdout, "Done.\n"); - } else if (ur) { - fprintf(stdout, "Read-UnProtecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_runprot_memory(stm); - fprintf(stdout, "Done.\n"); - } else if (eraseOnly) { - ret = 0; - fprintf(stdout, "Erasing flash\n"); - - if (num_pages != 0xff && - (start != flash_page_to_addr(first_page) - || end != flash_page_to_addr(first_page + num_pages))) { - fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); - ret = 1; - goto close; - } - - s_err = stm32_erase_memory(stm, first_page, num_pages); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to erase memory\n"); - ret = 1; - goto close; - } - } else if (wu) { - fprintf(diag, "Write-unprotecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_wunprot_memory(stm); - fprintf(diag, "Done.\n"); - - } else if (wr) { - fprintf(diag, "Write to memory\n"); - - off_t offset = 0; - ssize_t r; - unsigned int size; - unsigned int max_wlen, max_rlen; - - max_wlen = port_opts.tx_frame_max - 2; /* skip len and crc */ - max_wlen &= ~3; /* 32 bit aligned */ - - max_rlen = port_opts.rx_frame_max; - max_rlen = max_rlen < max_wlen ? max_rlen : max_wlen; - - /* Assume data from stdin is whole device */ - if (filename[0] == '-' && filename[1] == '\0') - size = end - start; - else - size = parser->size(p_st); - - // TODO: It is possible to write to non-page boundaries, by reading out flash - // from partial pages and combining with the input data - // if ((start % stm->dev->fl_ps) != 0 || (end % stm->dev->fl_ps) != 0) { - // fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); - // goto close; - // } - - // TODO: If writes are not page aligned, we should probably read out existing flash - // contents first, so it can be preserved and combined with new data - if (!no_erase && num_pages) { - fprintf(diag, "Erasing memory\n"); - s_err = stm32_erase_memory(stm, first_page, num_pages); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to erase memory\n"); - goto close; - } - } - - fflush(diag); - addr = start; - while(addr < end && offset < size) { - uint32_t left = end - addr; - len = max_wlen > left ? left : max_wlen; - len = len > size - offset ? size - offset : len; - - if (parser->read(p_st, buffer, &len) != PARSER_ERR_OK) - goto close; - - if (len == 0) { - if (filename[0] == '-') { - break; - } else { - fprintf(stderr, "Failed to read input file\n"); - goto close; - } - } - - again: - s_err = stm32_write_memory(stm, addr, buffer, len); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to write memory at address 0x%08x\n", addr); - goto close; - } - - if (verify) { - uint8_t compare[len]; - unsigned int offset, rlen; - - offset = 0; - while (offset < len) { - rlen = len - offset; - rlen = rlen < max_rlen ? rlen : max_rlen; - s_err = stm32_read_memory(stm, addr + offset, compare + offset, rlen); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read memory at address 0x%08x\n", addr + offset); - goto close; - } - offset += rlen; - } - - for(r = 0; r < len; ++r) - if (buffer[r] != compare[r]) { - if (failed == retry) { - fprintf(stderr, "Failed to verify at address 0x%08x, expected 0x%02x and found 0x%02x\n", - (uint32_t)(addr + r), - buffer [r], - compare[r] - ); - goto close; - } - ++failed; - goto again; - } - - failed = 0; - } - - addr += len; - offset += len; - - fprintf(diag, - "\rWrote %saddress 0x%08x (%.2f%%) ", - verify ? "and verified " : "", - addr, - (100.0f / size) * offset - ); - fflush(diag); - - } - - fprintf(diag, "Done.\n"); - ret = 0; - goto close; - } else if (crc) { - uint32_t crc_val = 0; - - fprintf(diag, "CRC computation\n"); - - s_err = stm32_crc_wrapper(stm, start, end - start, &crc_val); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read CRC\n"); - goto close; - } - fprintf(diag, "CRC(0x%08x-0x%08x) = 0x%08x\n", start, end, - crc_val); - ret = 0; - goto close; - } else - ret = 0; - -close: - if (stm && exec_flag && ret == 0) { - if (execute == 0) - execute = stm->dev->fl_start; - - fprintf(diag, "\nStarting execution at address 0x%08x... ", execute); - fflush(diag); - if (stm32_go(stm, execute) == STM32_ERR_OK) { - reset_flag = 0; - fprintf(diag, "done.\n"); - } else - fprintf(diag, "failed.\n"); - } - - if (stm && reset_flag) { - fprintf(diag, "\nResetting device... "); - fflush(diag); - if (init_bl_exit(stm, port, gpio_seq)) - fprintf(diag, "done.\n"); - else fprintf(diag, "failed.\n"); - } - - if (p_st ) parser->close(p_st); - if (stm ) stm32_close (stm); - if (port) - port->close(port); - - fprintf(diag, "\n"); - return ret; -} - -int parse_options(int argc, char *argv[]) -{ - int c; - char *pLen; - - while ((c = getopt(argc, argv, "a:b:m:r:w:e:vn:g:jkfcChuos:S:F:i:R")) != -1) { - switch(c) { - case 'a': - port_opts.bus_addr = strtoul(optarg, NULL, 0); - break; - - case 'b': - port_opts.baudRate = serial_get_baud(strtoul(optarg, NULL, 0)); - if (port_opts.baudRate == SERIAL_BAUD_INVALID) { - serial_baud_t baudrate; - fprintf(stderr, "Invalid baud rate, valid options are:\n"); - for (baudrate = SERIAL_BAUD_1200; baudrate != SERIAL_BAUD_INVALID; ++baudrate) - fprintf(stderr, " %d\n", serial_get_baud_int(baudrate)); - return 1; - } - break; - - case 'm': - if (strlen(optarg) != 3 - || serial_get_bits(optarg) == SERIAL_BITS_INVALID - || serial_get_parity(optarg) == SERIAL_PARITY_INVALID - || serial_get_stopbit(optarg) == SERIAL_STOPBIT_INVALID) { - fprintf(stderr, "Invalid serial mode\n"); - return 1; - } - port_opts.serial_mode = optarg; - break; - - case 'r': - case 'w': - rd = rd || c == 'r'; - wr = wr || c == 'w'; - if (rd && wr) { - fprintf(stderr, "ERROR: Invalid options, can't read & write at the same time\n"); - return 1; - } - filename = optarg; - if (filename[0] == '-') { - force_binary = 1; - } - break; - case 'e': - if (readwrite_len || start_addr) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } - npages = strtoul(optarg, NULL, 0); - if (npages > 0xFF || npages < 0) { - fprintf(stderr, "ERROR: You need to specify a page count between 0 and 255"); - return 1; - } - if (!npages) - no_erase = 1; - break; - case 'u': - wu = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't write unprotect and read/write at the same time\n"); - return 1; - } - break; - - case 'j': - rp = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't read protect and read/write at the same time\n"); - return 1; - } - break; - - case 'k': - ur = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't read unprotect and read/write at the same time\n"); - return 1; - } - break; - - case 'o': - eraseOnly = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't erase-only and read/write at the same time\n"); - return 1; - } - break; - - case 'v': - verify = 1; - break; - - case 'n': - retry = strtoul(optarg, NULL, 0); - break; - - case 'g': - exec_flag = 1; - execute = strtoul(optarg, NULL, 0); - if (execute % 4 != 0) { - fprintf(stderr, "ERROR: Execution address must be word-aligned\n"); - return 1; - } - break; - case 's': - if (readwrite_len || start_addr) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } - spage = strtoul(optarg, NULL, 0); - break; - case 'S': - if (spage || npages) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } else { - start_addr = strtoul(optarg, &pLen, 0); - if (*pLen == ':') { - pLen++; - readwrite_len = strtoul(pLen, NULL, 0); - if (readwrite_len == 0) { - fprintf(stderr, "ERROR: Invalid options, can't specify zero length\n"); - return 1; - } - } - } - break; - case 'F': - port_opts.rx_frame_max = strtoul(optarg, &pLen, 0); - if (*pLen == ':') { - pLen++; - port_opts.tx_frame_max = strtoul(pLen, NULL, 0); - } - if (port_opts.rx_frame_max < 0 - || port_opts.tx_frame_max < 0) { - fprintf(stderr, "ERROR: Invalid negative value for option -F\n"); - return 1; - } - if (port_opts.rx_frame_max == 0) - port_opts.rx_frame_max = STM32_MAX_RX_FRAME; - if (port_opts.tx_frame_max == 0) - port_opts.tx_frame_max = STM32_MAX_TX_FRAME; - if (port_opts.rx_frame_max < 20 - || port_opts.tx_frame_max < 5) { - fprintf(stderr, "ERROR: current code cannot work with small frames.\n"); - fprintf(stderr, "min(RX) = 20, min(TX) = 5\n"); - return 1; - } - if (port_opts.rx_frame_max > STM32_MAX_RX_FRAME) { - fprintf(stderr, "WARNING: Ignore RX length in option -F\n"); - port_opts.rx_frame_max = STM32_MAX_RX_FRAME; - } - if (port_opts.tx_frame_max > STM32_MAX_TX_FRAME) { - fprintf(stderr, "WARNING: Ignore TX length in option -F\n"); - port_opts.tx_frame_max = STM32_MAX_TX_FRAME; - } - break; - case 'f': - force_binary = 1; - break; - - case 'c': - init_flag = 0; - break; - - case 'h': - show_help(argv[0]); - exit(0); - - case 'i': - gpio_seq = optarg; - break; - - case 'R': - reset_flag = 1; - break; - - case 'C': - crc = 1; - break; - } - } - - for (c = optind; c < argc; ++c) { - if (port_opts.device) { - fprintf(stderr, "ERROR: Invalid parameter specified\n"); - show_help(argv[0]); - return 1; - } - port_opts.device = argv[c]; - } - - if (port_opts.device == NULL) { - fprintf(stderr, "ERROR: Device not specified\n"); - show_help(argv[0]); - return 1; - } - - if (!wr && verify) { - fprintf(stderr, "ERROR: Invalid usage, -v is only valid when writing\n"); - show_help(argv[0]); - return 1; - } - - return 0; -} - -void show_help(char *name) { - fprintf(stderr, - "Usage: %s [-bvngfhc] [-[rw] filename] [tty_device | i2c_device]\n" - " -a bus_address Bus address (e.g. for I2C port)\n" - " -b rate Baud rate (default 57600)\n" - " -m mode Serial port mode (default 8e1)\n" - " -r filename Read flash to file (or - stdout)\n" - " -w filename Write flash from file (or - stdout)\n" - " -C Compute CRC of flash content\n" - " -u Disable the flash write-protection\n" - " -j Enable the flash read-protection\n" - " -k Disable the flash read-protection\n" - " -o Erase only\n" - " -e n Only erase n pages before writing the flash\n" - " -v Verify writes\n" - " -n count Retry failed writes up to count times (default 10)\n" - " -g address Start execution at specified address (0 = flash start)\n" - " -S address[:length] Specify start address and optionally length for\n" - " read/write/erase operations\n" - " -F RX_length[:TX_length] Specify the max length of RX and TX frame\n" - " -s start_page Flash at specified page (0 = flash start)\n" - " -f Force binary parser\n" - " -h Show this help\n" - " -c Resume the connection (don't send initial INIT)\n" - " *Baud rate must be kept the same as the first init*\n" - " This is useful if the reset fails\n" - " -i GPIO_string GPIO sequence to enter/exit bootloader mode\n" - " GPIO_string=[entry_seq][:[exit_seq]]\n" - " sequence=[-]n[,sequence]\n" - " -R Reset device at exit.\n" - "\n" - "Examples:\n" - " Get device information:\n" - " %s /dev/ttyS0\n" - " or:\n" - " %s /dev/i2c-0\n" - "\n" - " Write with verify and then start execution:\n" - " %s -w filename -v -g 0x0 /dev/ttyS0\n" - "\n" - " Read flash to file:\n" - " %s -r filename /dev/ttyS0\n" - "\n" - " Read 100 bytes of flash from 0x1000 to stdout:\n" - " %s -r - -S 0x1000:100 /dev/ttyS0\n" - "\n" - " Start execution:\n" - " %s -g 0x0 /dev/ttyS0\n" - "\n" - " GPIO sequence:\n" - " - entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high\n" - " - exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high\n" - " %s -i -3,-2,2:3,-2,2 /dev/ttyS0\n", - name, - name, - name, - name, - name, - name, - name, - name - ); -} - diff --git a/linux64/src/stm32flash_serial/src/parsers/Android.mk b/linux64/src/stm32flash_serial/src/parsers/Android.mk deleted file mode 100644 index afec18cd5..000000000 --- a/linux64/src/stm32flash_serial/src/parsers/Android.mk +++ /dev/null @@ -1,6 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := libparsers -LOCAL_SRC_FILES := binary.c hex.c -include $(BUILD_STATIC_LIBRARY) diff --git a/linux64/src/stm32flash_serial/src/parsers/Makefile b/linux64/src/stm32flash_serial/src/parsers/Makefile deleted file mode 100644 index bb7df1e02..000000000 --- a/linux64/src/stm32flash_serial/src/parsers/Makefile +++ /dev/null @@ -1,12 +0,0 @@ - -CFLAGS += -Wall -g - -all: parsers.a - -parsers.a: binary.o hex.o - $(AR) rc $@ binary.o hex.o - -clean: - rm -f *.o parsers.a - -.PHONY: all clean diff --git a/linux64/src/stm32flash_serial/src/parsers/binary.c b/linux64/src/stm32flash_serial/src/parsers/binary.c deleted file mode 100644 index f491952bb..000000000 --- a/linux64/src/stm32flash_serial/src/parsers/binary.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include - -#include "binary.h" - -typedef struct { - int fd; - char write; - struct stat stat; -} binary_t; - -void* binary_init() { - return calloc(sizeof(binary_t), 1); -} - -parser_err_t binary_open(void *storage, const char *filename, const char write) { - binary_t *st = storage; - if (write) { - if (filename[0] == '-') - st->fd = 1; - else - st->fd = open( - filename, -#ifndef __WIN32__ - O_WRONLY | O_CREAT | O_TRUNC, -#else - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, -#endif -#ifndef __WIN32__ - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH -#else - 0 -#endif - ); - st->stat.st_size = 0; - } else { - if (filename[0] == '-') { - st->fd = 0; - } else { - if (stat(filename, &st->stat) != 0) - return PARSER_ERR_INVALID_FILE; - st->fd = open(filename, -#ifndef __WIN32__ - O_RDONLY -#else - O_RDONLY | O_BINARY -#endif - ); - } - } - - st->write = write; - return st->fd == -1 ? PARSER_ERR_SYSTEM : PARSER_ERR_OK; -} - -parser_err_t binary_close(void *storage) { - binary_t *st = storage; - - if (st->fd) close(st->fd); - free(st); - return PARSER_ERR_OK; -} - -unsigned int binary_size(void *storage) { - binary_t *st = storage; - return st->stat.st_size; -} - -parser_err_t binary_read(void *storage, void *data, unsigned int *len) { - binary_t *st = storage; - unsigned int left = *len; - if (st->write) return PARSER_ERR_WRONLY; - - ssize_t r; - while(left > 0) { - r = read(st->fd, data, left); - /* If there is no data to read at all, return OK, but with zero read */ - if (r == 0 && left == *len) { - *len = 0; - return PARSER_ERR_OK; - } - if (r <= 0) return PARSER_ERR_SYSTEM; - left -= r; - data += r; - } - - *len = *len - left; - return PARSER_ERR_OK; -} - -parser_err_t binary_write(void *storage, void *data, unsigned int len) { - binary_t *st = storage; - if (!st->write) return PARSER_ERR_RDONLY; - - ssize_t r; - while(len > 0) { - r = write(st->fd, data, len); - if (r < 1) return PARSER_ERR_SYSTEM; - st->stat.st_size += r; - - len -= r; - data += r; - } - - return PARSER_ERR_OK; -} - -parser_t PARSER_BINARY = { - "Raw BINARY", - binary_init, - binary_open, - binary_close, - binary_size, - binary_read, - binary_write -}; - diff --git a/linux64/src/stm32flash_serial/src/parsers/binary.h b/linux64/src/stm32flash_serial/src/parsers/binary.h deleted file mode 100644 index d989acfa0..000000000 --- a/linux64/src/stm32flash_serial/src/parsers/binary.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _PARSER_BINARY_H -#define _PARSER_BINARY_H - -#include "parser.h" - -extern parser_t PARSER_BINARY; -#endif diff --git a/linux64/src/stm32flash_serial/src/parsers/hex.c b/linux64/src/stm32flash_serial/src/parsers/hex.c deleted file mode 100644 index 3baf85623..000000000 --- a/linux64/src/stm32flash_serial/src/parsers/hex.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include - -#include "hex.h" -#include "../utils.h" - -typedef struct { - size_t data_len, offset; - uint8_t *data; - uint8_t base; -} hex_t; - -void* hex_init() { - return calloc(sizeof(hex_t), 1); -} - -parser_err_t hex_open(void *storage, const char *filename, const char write) { - hex_t *st = storage; - if (write) { - return PARSER_ERR_RDONLY; - } else { - char mark; - int i, fd; - uint8_t checksum; - unsigned int c; - uint32_t base = 0; - unsigned int last_address = 0x0; - - fd = open(filename, O_RDONLY); - if (fd < 0) - return PARSER_ERR_SYSTEM; - - /* read in the file */ - - while(read(fd, &mark, 1) != 0) { - if (mark == '\n' || mark == '\r') continue; - if (mark != ':') - return PARSER_ERR_INVALID_FILE; - - char buffer[9]; - unsigned int reclen, address, type; - uint8_t *record = NULL; - - /* get the reclen, address, and type */ - buffer[8] = 0; - if (read(fd, &buffer, 8) != 8) return PARSER_ERR_INVALID_FILE; - if (sscanf(buffer, "%2x%4x%2x", &reclen, &address, &type) != 3) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* setup the checksum */ - checksum = - reclen + - ((address & 0xFF00) >> 8) + - ((address & 0x00FF) >> 0) + - type; - - switch(type) { - /* data record */ - case 0: - c = address - last_address; - st->data = realloc(st->data, st->data_len + c + reclen); - - /* if there is a gap, set it to 0xff and increment the length */ - if (c > 0) { - memset(&st->data[st->data_len], 0xff, c); - st->data_len += c; - } - - last_address = address + reclen; - record = &st->data[st->data_len]; - st->data_len += reclen; - break; - - /* extended segment address record */ - case 2: - base = 0; - break; - - /* extended linear address record */ - case 4: - base = address; - break; - } - - buffer[2] = 0; - for(i = 0; i < reclen; ++i) { - if (read(fd, &buffer, 2) != 2 || sscanf(buffer, "%2x", &c) != 1) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* add the byte to the checksum */ - checksum += c; - - switch(type) { - case 0: - if (record != NULL) { - record[i] = c; - } else { - return PARSER_ERR_INVALID_FILE; - } - break; - - case 2: - case 4: - base = (base << 8) | c; - break; - } - } - - /* read, scan, and verify the checksum */ - if ( - read(fd, &buffer, 2 ) != 2 || - sscanf(buffer, "%2x", &c) != 1 || - (uint8_t)(checksum + c) != 0x00 - ) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - switch(type) { - /* EOF */ - case 1: - close(fd); - return PARSER_ERR_OK; - - /* address record */ - case 2: base = base << 4; - case 4: base = be_u32(base); - /* Reset last_address since our base changed */ - last_address = 0; - - if (st->base == 0) { - st->base = base; - break; - } - - /* we cant cope with files out of order */ - if (base < st->base) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* if there is a gap, enlarge and fill with zeros */ - unsigned int len = base - st->base; - if (len > st->data_len) { - st->data = realloc(st->data, len); - memset(&st->data[st->data_len], 0, len - st->data_len); - st->data_len = len; - } - break; - } - } - - close(fd); - return PARSER_ERR_OK; - } -} - -parser_err_t hex_close(void *storage) { - hex_t *st = storage; - if (st) free(st->data); - free(st); - return PARSER_ERR_OK; -} - -unsigned int hex_size(void *storage) { - hex_t *st = storage; - return st->data_len; -} - -parser_err_t hex_read(void *storage, void *data, unsigned int *len) { - hex_t *st = storage; - unsigned int left = st->data_len - st->offset; - unsigned int get = left > *len ? *len : left; - - memcpy(data, &st->data[st->offset], get); - st->offset += get; - - *len = get; - return PARSER_ERR_OK; -} - -parser_err_t hex_write(void *storage, void *data, unsigned int len) { - return PARSER_ERR_RDONLY; -} - -parser_t PARSER_HEX = { - "Intel HEX", - hex_init, - hex_open, - hex_close, - hex_size, - hex_read, - hex_write -}; - diff --git a/linux64/src/stm32flash_serial/src/parsers/hex.h b/linux64/src/stm32flash_serial/src/parsers/hex.h deleted file mode 100644 index 02413c9c9..000000000 --- a/linux64/src/stm32flash_serial/src/parsers/hex.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _PARSER_HEX_H -#define _PARSER_HEX_H - -#include "parser.h" - -extern parser_t PARSER_HEX; -#endif diff --git a/linux64/src/stm32flash_serial/src/parsers/parser.h b/linux64/src/stm32flash_serial/src/parsers/parser.h deleted file mode 100644 index c2fae3cf8..000000000 --- a/linux64/src/stm32flash_serial/src/parsers/parser.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_PARSER -#define _H_PARSER - -enum parser_err { - PARSER_ERR_OK, - PARSER_ERR_SYSTEM, - PARSER_ERR_INVALID_FILE, - PARSER_ERR_WRONLY, - PARSER_ERR_RDONLY -}; -typedef enum parser_err parser_err_t; - -struct parser { - const char *name; - void* (*init )(); /* initialise the parser */ - parser_err_t (*open )(void *storage, const char *filename, const char write); /* open the file for read|write */ - parser_err_t (*close)(void *storage); /* close and free the parser */ - unsigned int (*size )(void *storage); /* get the total data size */ - parser_err_t (*read )(void *storage, void *data, unsigned int *len); /* read a block of data */ - parser_err_t (*write)(void *storage, void *data, unsigned int len); /* write a block of data */ -}; -typedef struct parser parser_t; - -static inline const char* parser_errstr(parser_err_t err) { - switch(err) { - case PARSER_ERR_OK : return "OK"; - case PARSER_ERR_SYSTEM : return "System Error"; - case PARSER_ERR_INVALID_FILE: return "Invalid File"; - case PARSER_ERR_WRONLY : return "Parser can only write"; - case PARSER_ERR_RDONLY : return "Parser can only read"; - default: - return "Unknown Error"; - } -} - -#endif diff --git a/linux64/src/stm32flash_serial/src/port.c b/linux64/src/stm32flash_serial/src/port.c deleted file mode 100644 index 08e58cc34..000000000 --- a/linux64/src/stm32flash_serial/src/port.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include "serial.h" -#include "port.h" - - -extern struct port_interface port_serial; -extern struct port_interface port_i2c; - -static struct port_interface *ports[] = { - &port_serial, - &port_i2c, - NULL, -}; - - -port_err_t port_open(struct port_options *ops, struct port_interface **outport) -{ - int ret; - static struct port_interface **port; - - for (port = ports; *port; port++) { - ret = (*port)->open(*port, ops); - if (ret == PORT_ERR_NODEV) - continue; - if (ret == PORT_ERR_OK) - break; - fprintf(stderr, "Error probing interface \"%s\"\n", - (*port)->name); - } - if (*port == NULL) { - fprintf(stderr, "Cannot handle device \"%s\"\n", - ops->device); - return PORT_ERR_UNKNOWN; - } - - *outport = *port; - return PORT_ERR_OK; -} diff --git a/linux64/src/stm32flash_serial/src/port.h b/linux64/src/stm32flash_serial/src/port.h deleted file mode 100644 index 290f03496..000000000 --- a/linux64/src/stm32flash_serial/src/port.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_PORT -#define _H_PORT - -typedef enum { - PORT_ERR_OK = 0, - PORT_ERR_NODEV, /* No such device */ - PORT_ERR_TIMEDOUT, /* Operation timed out */ - PORT_ERR_UNKNOWN, -} port_err_t; - -/* flags */ -#define PORT_BYTE (1 << 0) /* byte (not frame) oriented */ -#define PORT_GVR_ETX (1 << 1) /* cmd GVR returns protection status */ -#define PORT_CMD_INIT (1 << 2) /* use INIT cmd to autodetect speed */ -#define PORT_RETRY (1 << 3) /* allowed read() retry after timeout */ -#define PORT_STRETCH_W (1 << 4) /* warning for no-stretching commands */ - -/* all options and flags used to open and configure an interface */ -struct port_options { - const char *device; - serial_baud_t baudRate; - const char *serial_mode; - int bus_addr; - int rx_frame_max; - int tx_frame_max; -}; - -/* - * Specify the length of reply for command GET - * This is helpful for frame-oriented protocols, e.g. i2c, to avoid time - * consuming try-fail-timeout-retry operation. - * On byte-oriented protocols, i.e. UART, this information would be skipped - * after read the first byte, so not needed. - */ -struct varlen_cmd { - uint8_t version; - uint8_t length; -}; - -struct port_interface { - const char *name; - unsigned flags; - port_err_t (*open)(struct port_interface *port, struct port_options *ops); - port_err_t (*close)(struct port_interface *port); - port_err_t (*read)(struct port_interface *port, void *buf, size_t nbyte); - port_err_t (*write)(struct port_interface *port, void *buf, size_t nbyte); - port_err_t (*gpio)(struct port_interface *port, serial_gpio_t n, int level); - const char *(*get_cfg_str)(struct port_interface *port); - struct varlen_cmd *cmd_get_reply; - void *private; -}; - -port_err_t port_open(struct port_options *ops, struct port_interface **outport); - -#endif diff --git a/linux64/src/stm32flash_serial/src/protocol.txt b/linux64/src/stm32flash_serial/src/protocol.txt deleted file mode 100644 index 039109908..000000000 --- a/linux64/src/stm32flash_serial/src/protocol.txt +++ /dev/null @@ -1,19 +0,0 @@ -The communication protocol used by ST bootloader is documented in following ST -application notes, depending on communication port. - -In current version of stm32flash are supported only UART and I2C ports. - -* AN3154: CAN protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/CD00264321.pdf - -* AN3155: USART protocol used in the STM32(TM) bootloader - http://www.st.com/web/en/resource/technical/document/application_note/CD00264342.pdf - -* AN4221: I2C protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/DM00072315.pdf - -* AN4286: SPI protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/DM00081379.pdf - -Boot mode selection for STM32 is documented in ST application note AN2606, available in ST website: - http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf diff --git a/linux64/src/stm32flash_serial/src/serial.h b/linux64/src/stm32flash_serial/src/serial.h deleted file mode 100644 index 227ba163b..000000000 --- a/linux64/src/stm32flash_serial/src/serial.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _SERIAL_H -#define _SERIAL_H - -typedef struct serial serial_t; - -typedef enum { - SERIAL_PARITY_NONE, - SERIAL_PARITY_EVEN, - SERIAL_PARITY_ODD, - - SERIAL_PARITY_INVALID -} serial_parity_t; - -typedef enum { - SERIAL_BITS_5, - SERIAL_BITS_6, - SERIAL_BITS_7, - SERIAL_BITS_8, - - SERIAL_BITS_INVALID -} serial_bits_t; - -typedef enum { - SERIAL_BAUD_1200, - SERIAL_BAUD_1800, - SERIAL_BAUD_2400, - SERIAL_BAUD_4800, - SERIAL_BAUD_9600, - SERIAL_BAUD_19200, - SERIAL_BAUD_38400, - SERIAL_BAUD_57600, - SERIAL_BAUD_115200, - SERIAL_BAUD_128000, - SERIAL_BAUD_230400, - SERIAL_BAUD_256000, - SERIAL_BAUD_460800, - SERIAL_BAUD_500000, - SERIAL_BAUD_576000, - SERIAL_BAUD_921600, - SERIAL_BAUD_1000000, - SERIAL_BAUD_1500000, - SERIAL_BAUD_2000000, - - SERIAL_BAUD_INVALID -} serial_baud_t; - -typedef enum { - SERIAL_STOPBIT_1, - SERIAL_STOPBIT_2, - - SERIAL_STOPBIT_INVALID -} serial_stopbit_t; - -typedef enum { - GPIO_RTS = 1, - GPIO_DTR, - GPIO_BRK, -} serial_gpio_t; - -/* common helper functions */ -serial_baud_t serial_get_baud(const unsigned int baud); -unsigned int serial_get_baud_int(const serial_baud_t baud); -serial_bits_t serial_get_bits(const char *mode); -unsigned int serial_get_bits_int(const serial_bits_t bits); -serial_parity_t serial_get_parity(const char *mode); -char serial_get_parity_str(const serial_parity_t parity); -serial_stopbit_t serial_get_stopbit(const char *mode); -unsigned int serial_get_stopbit_int(const serial_stopbit_t stopbit); - -#endif diff --git a/linux64/src/stm32flash_serial/src/serial_common.c b/linux64/src/stm32flash_serial/src/serial_common.c deleted file mode 100644 index 43e48e1ac..000000000 --- a/linux64/src/stm32flash_serial/src/serial_common.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "serial.h" - -serial_baud_t serial_get_baud(const unsigned int baud) { - switch(baud) { - case 1200: return SERIAL_BAUD_1200 ; - case 1800: return SERIAL_BAUD_1800 ; - case 2400: return SERIAL_BAUD_2400 ; - case 4800: return SERIAL_BAUD_4800 ; - case 9600: return SERIAL_BAUD_9600 ; - case 19200: return SERIAL_BAUD_19200 ; - case 38400: return SERIAL_BAUD_38400 ; - case 57600: return SERIAL_BAUD_57600 ; - case 115200: return SERIAL_BAUD_115200; - case 128000: return SERIAL_BAUD_128000; - case 230400: return SERIAL_BAUD_230400; - case 256000: return SERIAL_BAUD_256000; - case 460800: return SERIAL_BAUD_460800; - case 500000: return SERIAL_BAUD_500000; - case 576000: return SERIAL_BAUD_576000; - case 921600: return SERIAL_BAUD_921600; - case 1000000: return SERIAL_BAUD_1000000; - case 1500000: return SERIAL_BAUD_1500000; - case 2000000: return SERIAL_BAUD_2000000; - - default: - return SERIAL_BAUD_INVALID; - } -} - -unsigned int serial_get_baud_int(const serial_baud_t baud) { - switch(baud) { - case SERIAL_BAUD_1200 : return 1200 ; - case SERIAL_BAUD_1800 : return 1800 ; - case SERIAL_BAUD_2400 : return 2400 ; - case SERIAL_BAUD_4800 : return 4800 ; - case SERIAL_BAUD_9600 : return 9600 ; - case SERIAL_BAUD_19200 : return 19200 ; - case SERIAL_BAUD_38400 : return 38400 ; - case SERIAL_BAUD_57600 : return 57600 ; - case SERIAL_BAUD_115200: return 115200; - case SERIAL_BAUD_128000: return 128000; - case SERIAL_BAUD_230400: return 230400; - case SERIAL_BAUD_256000: return 256000; - case SERIAL_BAUD_460800: return 460800; - case SERIAL_BAUD_500000: return 500000; - case SERIAL_BAUD_576000: return 576000; - case SERIAL_BAUD_921600: return 921600; - case SERIAL_BAUD_1000000: return 1000000; - case SERIAL_BAUD_1500000: return 1500000; - case SERIAL_BAUD_2000000: return 2000000; - - case SERIAL_BAUD_INVALID: - default: - return 0; - } -} - -serial_bits_t serial_get_bits(const char *mode) { - if (!mode) - return SERIAL_BITS_INVALID; - switch(mode[0]) { - case '5': return SERIAL_BITS_5; - case '6': return SERIAL_BITS_6; - case '7': return SERIAL_BITS_7; - case '8': return SERIAL_BITS_8; - - default: - return SERIAL_BITS_INVALID; - } -} - -unsigned int serial_get_bits_int(const serial_bits_t bits) { - switch(bits) { - case SERIAL_BITS_5: return 5; - case SERIAL_BITS_6: return 6; - case SERIAL_BITS_7: return 7; - case SERIAL_BITS_8: return 8; - - default: - return 0; - } -} - -serial_parity_t serial_get_parity(const char *mode) { - if (!mode || !mode[0]) - return SERIAL_PARITY_INVALID; - switch(mode[1]) { - case 'N': - case 'n': - return SERIAL_PARITY_NONE; - case 'E': - case 'e': - return SERIAL_PARITY_EVEN; - case 'O': - case 'o': - return SERIAL_PARITY_ODD; - - default: - return SERIAL_PARITY_INVALID; - } -} - -char serial_get_parity_str(const serial_parity_t parity) { - switch(parity) { - case SERIAL_PARITY_NONE: return 'N'; - case SERIAL_PARITY_EVEN: return 'E'; - case SERIAL_PARITY_ODD : return 'O'; - - default: - return ' '; - } -} - -serial_stopbit_t serial_get_stopbit(const char *mode) { - if (!mode || !mode[0] || !mode[1]) - return SERIAL_STOPBIT_INVALID; - switch(mode[2]) { - case '1': return SERIAL_STOPBIT_1; - case '2': return SERIAL_STOPBIT_2; - - default: - return SERIAL_STOPBIT_INVALID; - } -} - -unsigned int serial_get_stopbit_int(const serial_stopbit_t stopbit) { - switch(stopbit) { - case SERIAL_STOPBIT_1: return 1; - case SERIAL_STOPBIT_2: return 2; - - default: - return 0; - } -} - diff --git a/linux64/src/stm32flash_serial/src/serial_platform.c b/linux64/src/stm32flash_serial/src/serial_platform.c deleted file mode 100644 index 98e256921..000000000 --- a/linux64/src/stm32flash_serial/src/serial_platform.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined(__WIN32__) || defined(__CYGWIN__) -# include "serial_w32.c" -#else -# include "serial_posix.c" -#endif diff --git a/linux64/src/stm32flash_serial/src/serial_posix.c b/linux64/src/stm32flash_serial/src/serial_posix.c deleted file mode 100644 index 284b35b20..000000000 --- a/linux64/src/stm32flash_serial/src/serial_posix.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - -struct serial { - int fd; - struct termios oldtio; - struct termios newtio; - char setup_str[11]; -}; - -static serial_t *serial_open(const char *device) -{ - serial_t *h = calloc(sizeof(serial_t), 1); - - h->fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); - if (h->fd < 0) { - free(h); - return NULL; - } - fcntl(h->fd, F_SETFL, 0); - - tcgetattr(h->fd, &h->oldtio); - tcgetattr(h->fd, &h->newtio); - - return h; -} - -static void serial_flush(const serial_t *h) -{ - tcflush(h->fd, TCIFLUSH); -} - -static void serial_close(serial_t *h) -{ - serial_flush(h); - tcsetattr(h->fd, TCSANOW, &h->oldtio); - close(h->fd); - free(h); -} - -static port_err_t serial_setup(serial_t *h, const serial_baud_t baud, - const serial_bits_t bits, - const serial_parity_t parity, - const serial_stopbit_t stopbit) -{ - speed_t port_baud; - tcflag_t port_bits; - tcflag_t port_parity; - tcflag_t port_stop; - struct termios settings; - - switch (baud) { - case SERIAL_BAUD_1200: port_baud = B1200; break; - case SERIAL_BAUD_1800: port_baud = B1800; break; - case SERIAL_BAUD_2400: port_baud = B2400; break; - case SERIAL_BAUD_4800: port_baud = B4800; break; - case SERIAL_BAUD_9600: port_baud = B9600; break; - case SERIAL_BAUD_19200: port_baud = B19200; break; - case SERIAL_BAUD_38400: port_baud = B38400; break; - case SERIAL_BAUD_57600: port_baud = B57600; break; - case SERIAL_BAUD_115200: port_baud = B115200; break; - case SERIAL_BAUD_230400: port_baud = B230400; break; -#ifdef B460800 - case SERIAL_BAUD_460800: port_baud = B460800; break; -#endif /* B460800 */ -#ifdef B921600 - case SERIAL_BAUD_921600: port_baud = B921600; break; -#endif /* B921600 */ -#ifdef B500000 - case SERIAL_BAUD_500000: port_baud = B500000; break; -#endif /* B500000 */ -#ifdef B576000 - case SERIAL_BAUD_576000: port_baud = B576000; break; -#endif /* B576000 */ -#ifdef B1000000 - case SERIAL_BAUD_1000000: port_baud = B1000000; break; -#endif /* B1000000 */ -#ifdef B1500000 - case SERIAL_BAUD_1500000: port_baud = B1500000; break; -#endif /* B1500000 */ -#ifdef B2000000 - case SERIAL_BAUD_2000000: port_baud = B2000000; break; -#endif /* B2000000 */ - - case SERIAL_BAUD_INVALID: - default: - return PORT_ERR_UNKNOWN; - } - - switch (bits) { - case SERIAL_BITS_5: port_bits = CS5; break; - case SERIAL_BITS_6: port_bits = CS6; break; - case SERIAL_BITS_7: port_bits = CS7; break; - case SERIAL_BITS_8: port_bits = CS8; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (parity) { - case SERIAL_PARITY_NONE: port_parity = 0; break; - case SERIAL_PARITY_EVEN: port_parity = PARENB; break; - case SERIAL_PARITY_ODD: port_parity = PARENB | PARODD; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (stopbit) { - case SERIAL_STOPBIT_1: port_stop = 0; break; - case SERIAL_STOPBIT_2: port_stop = CSTOPB; break; - - default: - return PORT_ERR_UNKNOWN; - } - - /* reset the settings */ -#ifndef __sun /* Used by GNU and BSD. Ignore __SVR4 in test. */ - cfmakeraw(&h->newtio); -#else /* __sun */ - h->newtio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR - | IGNCR | ICRNL | IXON); - if (port_parity) - h->newtio.c_iflag |= INPCK; - - h->newtio.c_oflag &= ~OPOST; - h->newtio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - h->newtio.c_cflag &= ~(CSIZE | PARENB); - h->newtio.c_cflag |= CS8; -#endif /* __sun */ -#ifdef __QNXNTO__ - h->newtio.c_cflag &= ~(CSIZE | IHFLOW | OHFLOW); -#else - h->newtio.c_cflag &= ~(CSIZE | CRTSCTS); -#endif - h->newtio.c_cflag &= ~(CSIZE | CRTSCTS); - h->newtio.c_iflag &= ~(IXON | IXOFF | IXANY | IGNPAR); - h->newtio.c_lflag &= ~(ECHOK | ECHOCTL | ECHOKE); - h->newtio.c_oflag &= ~(OPOST | ONLCR); - - /* setup the new settings */ - cfsetispeed(&h->newtio, port_baud); - cfsetospeed(&h->newtio, port_baud); - h->newtio.c_cflag |= - port_parity | - port_bits | - port_stop | - CLOCAL | - CREAD; - - h->newtio.c_cc[VMIN] = 0; - h->newtio.c_cc[VTIME] = 5; /* in units of 0.1 s */ - - /* set the settings */ - serial_flush(h); - if (tcsetattr(h->fd, TCSANOW, &h->newtio) != 0) - return PORT_ERR_UNKNOWN; - -/* this check fails on CDC-ACM devices, bits 16 and 17 of cflag differ! - * it has been disabled below for now -jcw, 2015-11-09 - if (settings.c_cflag != h->newtio.c_cflag) - fprintf(stderr, "c_cflag mismatch %lx\n", - settings.c_cflag ^ h->newtio.c_cflag); - */ - - /* confirm they were set */ - tcgetattr(h->fd, &settings); - if (settings.c_iflag != h->newtio.c_iflag || - settings.c_oflag != h->newtio.c_oflag || - //settings.c_cflag != h->newtio.c_cflag || - settings.c_lflag != h->newtio.c_lflag) - return PORT_ERR_UNKNOWN; - - snprintf(h->setup_str, sizeof(h->setup_str), "%u %d%c%d", - serial_get_baud_int(baud), - serial_get_bits_int(bits), - serial_get_parity_str(parity), - serial_get_stopbit_int(stopbit)); - return PORT_ERR_OK; -} - -/* - * Roger clark. - * This function is no longer used. But has just been commented out in case it needs - * to be reinstated in the future - -static int startswith(const char *haystack, const char *needle) { - return strncmp(haystack, needle, strlen(needle)) == 0; -} -*/ - -static int is_tty(const char *path) { - char resolved[PATH_MAX]; - - if(!realpath(path, resolved)) return 0; - - - /* - * Roger Clark - * Commented out this check, because on OSX some devices are /dev/cu - * and some users use symbolic links to devices, hence the name may not even start - * with /dev - - if(startswith(resolved, "/dev/tty")) return 1; - - return 0; - */ - - return 1; -} - -static port_err_t serial_posix_open(struct port_interface *port, - struct port_options *ops) -{ - serial_t *h; - - /* 1. check device name match */ - if (!is_tty(ops->device)) - return PORT_ERR_NODEV; - - /* 2. check options */ - if (ops->baudRate == SERIAL_BAUD_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_parity(ops->serial_mode) == SERIAL_PARITY_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) - return PORT_ERR_UNKNOWN; - - /* 3. open it */ - h = serial_open(ops->device); - if (h == NULL) - return PORT_ERR_UNKNOWN; - - /* 4. set options */ - if (serial_setup(h, ops->baudRate, - serial_get_bits(ops->serial_mode), - serial_get_parity(ops->serial_mode), - serial_get_stopbit(ops->serial_mode) - ) != PORT_ERR_OK) { - serial_close(h); - return PORT_ERR_UNKNOWN; - } - - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t serial_posix_close(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - serial_close(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t serial_posix_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - ssize_t r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - r = read(h->fd, pos, nbyte); - if (r == 0) - return PORT_ERR_TIMEDOUT; - if (r < 0) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_posix_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - ssize_t r; - const uint8_t *pos = (const uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - r = write(h->fd, pos, nbyte); - if (r < 1) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_posix_gpio(struct port_interface *port, - serial_gpio_t n, int level) -{ - serial_t *h; - int bit, lines; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - switch (n) { - case GPIO_RTS: - bit = TIOCM_RTS; - break; - - case GPIO_DTR: - bit = TIOCM_DTR; - break; - - case GPIO_BRK: - if (level == 0) - return PORT_ERR_OK; - if (tcsendbreak(h->fd, 1)) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; - - default: - return PORT_ERR_UNKNOWN; - } - - /* handle RTS/DTR */ - if (ioctl(h->fd, TIOCMGET, &lines)) - return PORT_ERR_UNKNOWN; - lines = level ? lines | bit : lines & ~bit; - if (ioctl(h->fd, TIOCMSET, &lines)) - return PORT_ERR_UNKNOWN; - - return PORT_ERR_OK; -} - -static const char *serial_posix_get_cfg_str(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - return h ? h->setup_str : "INVALID"; -} - -struct port_interface port_serial = { - .name = "serial_posix", - .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, - .open = serial_posix_open, - .close = serial_posix_close, - .read = serial_posix_read, - .write = serial_posix_write, - .gpio = serial_posix_gpio, - .get_cfg_str = serial_posix_get_cfg_str, -}; diff --git a/linux64/src/stm32flash_serial/src/serial_w32.c b/linux64/src/stm32flash_serial/src/serial_w32.c deleted file mode 100644 index 56772c0a0..000000000 --- a/linux64/src/stm32flash_serial/src/serial_w32.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2010 Gareth McMullin - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - -struct serial { - HANDLE fd; - DCB oldtio; - DCB newtio; - char setup_str[11]; -}; - -static serial_t *serial_open(const char *device) -{ - serial_t *h = calloc(sizeof(serial_t), 1); - char *devName; - - /* timeout in ms */ - COMMTIMEOUTS timeouts = {MAXDWORD, MAXDWORD, 500, 0, 0}; - - /* Fix the device name if required */ - if (strlen(device) > 4 && device[0] != '\\') { - devName = calloc(1, strlen(device) + 5); - sprintf(devName, "\\\\.\\%s", device); - } else { - devName = (char *)device; - } - - /* Create file handle for port */ - h->fd = CreateFile(devName, GENERIC_READ | GENERIC_WRITE, - 0, /* Exclusive access */ - NULL, /* No security */ - OPEN_EXISTING, - 0, /* No overlap */ - NULL); - - if (devName != device) - free(devName); - - if (h->fd == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_FILE_NOT_FOUND) - fprintf(stderr, "File not found: %s\n", device); - return NULL; - } - - SetupComm(h->fd, 4096, 4096); /* Set input and output buffer size */ - - SetCommTimeouts(h->fd, &timeouts); - - SetCommMask(h->fd, EV_ERR); /* Notify us of error events */ - - GetCommState(h->fd, &h->oldtio); /* Retrieve port parameters */ - GetCommState(h->fd, &h->newtio); /* Retrieve port parameters */ - - /* PurgeComm(h->fd, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); */ - - return h; -} - -static void serial_flush(const serial_t *h) -{ - /* We shouldn't need to flush in non-overlapping (blocking) mode */ - /* tcflush(h->fd, TCIFLUSH); */ -} - -static void serial_close(serial_t *h) -{ - serial_flush(h); - SetCommState(h->fd, &h->oldtio); - CloseHandle(h->fd); - free(h); -} - -static port_err_t serial_setup(serial_t *h, - const serial_baud_t baud, - const serial_bits_t bits, - const serial_parity_t parity, - const serial_stopbit_t stopbit) -{ - switch (baud) { - case SERIAL_BAUD_1200: h->newtio.BaudRate = CBR_1200; break; - /* case SERIAL_BAUD_1800: h->newtio.BaudRate = CBR_1800; break; */ - case SERIAL_BAUD_2400: h->newtio.BaudRate = CBR_2400; break; - case SERIAL_BAUD_4800: h->newtio.BaudRate = CBR_4800; break; - case SERIAL_BAUD_9600: h->newtio.BaudRate = CBR_9600; break; - case SERIAL_BAUD_19200: h->newtio.BaudRate = CBR_19200; break; - case SERIAL_BAUD_38400: h->newtio.BaudRate = CBR_38400; break; - case SERIAL_BAUD_57600: h->newtio.BaudRate = CBR_57600; break; - case SERIAL_BAUD_115200: h->newtio.BaudRate = CBR_115200; break; - case SERIAL_BAUD_128000: h->newtio.BaudRate = CBR_128000; break; - case SERIAL_BAUD_256000: h->newtio.BaudRate = CBR_256000; break; - /* These are not defined in WinBase.h and might work or not */ - case SERIAL_BAUD_230400: h->newtio.BaudRate = 230400; break; - case SERIAL_BAUD_460800: h->newtio.BaudRate = 460800; break; - case SERIAL_BAUD_500000: h->newtio.BaudRate = 500000; break; - case SERIAL_BAUD_576000: h->newtio.BaudRate = 576000; break; - case SERIAL_BAUD_921600: h->newtio.BaudRate = 921600; break; - case SERIAL_BAUD_1000000: h->newtio.BaudRate = 1000000; break; - case SERIAL_BAUD_1500000: h->newtio.BaudRate = 1500000; break; - case SERIAL_BAUD_2000000: h->newtio.BaudRate = 2000000; break; - case SERIAL_BAUD_INVALID: - - default: - return PORT_ERR_UNKNOWN; - } - - switch (bits) { - case SERIAL_BITS_5: h->newtio.ByteSize = 5; break; - case SERIAL_BITS_6: h->newtio.ByteSize = 6; break; - case SERIAL_BITS_7: h->newtio.ByteSize = 7; break; - case SERIAL_BITS_8: h->newtio.ByteSize = 8; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (parity) { - case SERIAL_PARITY_NONE: h->newtio.Parity = NOPARITY; break; - case SERIAL_PARITY_EVEN: h->newtio.Parity = EVENPARITY; break; - case SERIAL_PARITY_ODD: h->newtio.Parity = ODDPARITY; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (stopbit) { - case SERIAL_STOPBIT_1: h->newtio.StopBits = ONESTOPBIT; break; - case SERIAL_STOPBIT_2: h->newtio.StopBits = TWOSTOPBITS; break; - - default: - return PORT_ERR_UNKNOWN; - } - - /* reset the settings */ - h->newtio.fOutxCtsFlow = FALSE; - h->newtio.fOutxDsrFlow = FALSE; - h->newtio.fOutX = FALSE; - h->newtio.fInX = FALSE; - h->newtio.fNull = 0; - h->newtio.fAbortOnError = 0; - - /* set the settings */ - serial_flush(h); - if (!SetCommState(h->fd, &h->newtio)) - return PORT_ERR_UNKNOWN; - - snprintf(h->setup_str, sizeof(h->setup_str), "%u %d%c%d", - serial_get_baud_int(baud), - serial_get_bits_int(bits), - serial_get_parity_str(parity), - serial_get_stopbit_int(stopbit) - ); - return PORT_ERR_OK; -} - -static port_err_t serial_w32_open(struct port_interface *port, - struct port_options *ops) -{ - serial_t *h; - - /* 1. check device name match */ - if (!((strlen(ops->device) == 4 || strlen(ops->device) == 5) - && !strncmp(ops->device, "COM", 3) && isdigit(ops->device[3])) - && !(!strncmp(ops->device, "\\\\.\\COM", strlen("\\\\.\\COM")) - && isdigit(ops->device[strlen("\\\\.\\COM")]))) - return PORT_ERR_NODEV; - - /* 2. check options */ - if (ops->baudRate == SERIAL_BAUD_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_parity(ops->serial_mode) == SERIAL_PARITY_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) - return PORT_ERR_UNKNOWN; - - /* 3. open it */ - h = serial_open(ops->device); - if (h == NULL) - return PORT_ERR_UNKNOWN; - - /* 4. set options */ - if (serial_setup(h, ops->baudRate, - serial_get_bits(ops->serial_mode), - serial_get_parity(ops->serial_mode), - serial_get_stopbit(ops->serial_mode) - ) != PORT_ERR_OK) { - serial_close(h); - return PORT_ERR_UNKNOWN; - } - - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t serial_w32_close(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - serial_close(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t serial_w32_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - DWORD r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - ReadFile(h->fd, pos, nbyte, &r, NULL); - if (r == 0) - return PORT_ERR_TIMEDOUT; - if (r < 0) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_w32_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - DWORD r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - if (!WriteFile(h->fd, pos, nbyte, &r, NULL)) - return PORT_ERR_UNKNOWN; - if (r < 1) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_w32_gpio(struct port_interface *port, - serial_gpio_t n, int level) -{ - serial_t *h; - int bit; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - switch (n) { - case GPIO_RTS: - bit = level ? SETRTS : CLRRTS; - break; - - case GPIO_DTR: - bit = level ? SETDTR : CLRDTR; - break; - - case GPIO_BRK: - if (level == 0) - return PORT_ERR_OK; - if (EscapeCommFunction(h->fd, SETBREAK) == 0) - return PORT_ERR_UNKNOWN; - usleep(500000); - if (EscapeCommFunction(h->fd, CLRBREAK) == 0) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; - - default: - return PORT_ERR_UNKNOWN; - } - - /* handle RTS/DTR */ - if (EscapeCommFunction(h->fd, bit) == 0) - return PORT_ERR_UNKNOWN; - - return PORT_ERR_OK; -} - -static const char *serial_w32_get_cfg_str(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - return h ? h->setup_str : "INVALID"; -} - -struct port_interface port_serial = { - .name = "serial_w32", - .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, - .open = serial_w32_open, - .close = serial_w32_close, - .read = serial_w32_read, - .write = serial_w32_write, - .gpio = serial_w32_gpio, - .get_cfg_str = serial_w32_get_cfg_str, -}; diff --git a/linux64/src/stm32flash_serial/src/stm32.c b/linux64/src/stm32flash_serial/src/stm32.c deleted file mode 100644 index 74047d244..000000000 --- a/linux64/src/stm32flash_serial/src/stm32.c +++ /dev/null @@ -1,1048 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright 2010 Geoffrey McRae - Copyright 2012-2014 Tormod Volden - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include - -#include "stm32.h" -#include "port.h" -#include "utils.h" - -#define STM32_ACK 0x79 -#define STM32_NACK 0x1F -#define STM32_BUSY 0x76 - -#define STM32_CMD_INIT 0x7F -#define STM32_CMD_GET 0x00 /* get the version and command supported */ -#define STM32_CMD_GVR 0x01 /* get version and read protection status */ -#define STM32_CMD_GID 0x02 /* get ID */ -#define STM32_CMD_RM 0x11 /* read memory */ -#define STM32_CMD_GO 0x21 /* go */ -#define STM32_CMD_WM 0x31 /* write memory */ -#define STM32_CMD_WM_NS 0x32 /* no-stretch write memory */ -#define STM32_CMD_ER 0x43 /* erase */ -#define STM32_CMD_EE 0x44 /* extended erase */ -#define STM32_CMD_EE_NS 0x45 /* extended erase no-stretch */ -#define STM32_CMD_WP 0x63 /* write protect */ -#define STM32_CMD_WP_NS 0x64 /* write protect no-stretch */ -#define STM32_CMD_UW 0x73 /* write unprotect */ -#define STM32_CMD_UW_NS 0x74 /* write unprotect no-stretch */ -#define STM32_CMD_RP 0x82 /* readout protect */ -#define STM32_CMD_RP_NS 0x83 /* readout protect no-stretch */ -#define STM32_CMD_UR 0x92 /* readout unprotect */ -#define STM32_CMD_UR_NS 0x93 /* readout unprotect no-stretch */ -#define STM32_CMD_CRC 0xA1 /* compute CRC */ -#define STM32_CMD_ERR 0xFF /* not a valid command */ - -#define STM32_RESYNC_TIMEOUT 35 /* seconds */ -#define STM32_MASSERASE_TIMEOUT 35 /* seconds */ -#define STM32_SECTERASE_TIMEOUT 5 /* seconds */ -#define STM32_BLKWRITE_TIMEOUT 1 /* seconds */ -#define STM32_WUNPROT_TIMEOUT 1 /* seconds */ -#define STM32_WPROT_TIMEOUT 1 /* seconds */ -#define STM32_RPROT_TIMEOUT 1 /* seconds */ - -#define STM32_CMD_GET_LENGTH 17 /* bytes in the reply */ - -struct stm32_cmd { - uint8_t get; - uint8_t gvr; - uint8_t gid; - uint8_t rm; - uint8_t go; - uint8_t wm; - uint8_t er; /* this may be extended erase */ - uint8_t wp; - uint8_t uw; - uint8_t rp; - uint8_t ur; - uint8_t crc; -}; - -/* Reset code for ARMv7-M (Cortex-M3) and ARMv6-M (Cortex-M0) - * see ARMv7-M or ARMv6-M Architecture Reference Manual (table B3-8) - * or "The definitive guide to the ARM Cortex-M3", section 14.4. - */ -static const uint8_t stm_reset_code[] = { - 0x01, 0x49, // ldr r1, [pc, #4] ; () - 0x02, 0x4A, // ldr r2, [pc, #8] ; () - 0x0A, 0x60, // str r2, [r1, #0] - 0xfe, 0xe7, // endless: b endless - 0x0c, 0xed, 0x00, 0xe0, // .word 0xe000ed0c = NVIC AIRCR register address - 0x04, 0x00, 0xfa, 0x05 // .word 0x05fa0004 = VECTKEY | SYSRESETREQ -}; - -static const uint32_t stm_reset_code_length = sizeof(stm_reset_code); - -extern const stm32_dev_t devices[]; - -static void stm32_warn_stretching(const char *f) -{ - fprintf(stderr, "Attention !!!\n"); - fprintf(stderr, "\tThis %s error could be caused by your I2C\n", f); - fprintf(stderr, "\tcontroller not accepting \"clock stretching\"\n"); - fprintf(stderr, "\tas required by bootloader.\n"); - fprintf(stderr, "\tCheck \"I2C.txt\" in stm32flash source code.\n"); -} - -static stm32_err_t stm32_get_ack_timeout(const stm32_t *stm, time_t timeout) -{ - struct port_interface *port = stm->port; - uint8_t byte; - port_err_t p_err; - time_t t0, t1; - - if (!(port->flags & PORT_RETRY)) - timeout = 0; - - if (timeout) - time(&t0); - - do { - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_TIMEDOUT && timeout) { - time(&t1); - if (t1 < t0 + timeout) - continue; - } - - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to read ACK byte\n"); - return STM32_ERR_UNKNOWN; - } - - if (byte == STM32_ACK) - return STM32_ERR_OK; - if (byte == STM32_NACK) - return STM32_ERR_NACK; - if (byte != STM32_BUSY) { - fprintf(stderr, "Got byte 0x%02x instead of ACK\n", - byte); - return STM32_ERR_UNKNOWN; - } - } while (1); -} - -static stm32_err_t stm32_get_ack(const stm32_t *stm) -{ - return stm32_get_ack_timeout(stm, 0); -} - -static stm32_err_t stm32_send_command_timeout(const stm32_t *stm, - const uint8_t cmd, - time_t timeout) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - port_err_t p_err; - uint8_t buf[2]; - - buf[0] = cmd; - buf[1] = cmd ^ 0xFF; - p_err = port->write(port, buf, 2); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send command\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, timeout); - if (s_err == STM32_ERR_OK) - return STM32_ERR_OK; - if (s_err == STM32_ERR_NACK) - fprintf(stderr, "Got NACK from device on command 0x%02x\n", cmd); - else - fprintf(stderr, "Unexpected reply from device on command 0x%02x\n", cmd); - return STM32_ERR_UNKNOWN; -} - -static stm32_err_t stm32_send_command(const stm32_t *stm, const uint8_t cmd) -{ - return stm32_send_command_timeout(stm, cmd, 0); -} - -/* if we have lost sync, send a wrong command and expect a NACK */ -static stm32_err_t stm32_resync(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - uint8_t buf[2], ack; - time_t t0, t1; - - time(&t0); - t1 = t0; - - buf[0] = STM32_CMD_ERR; - buf[1] = STM32_CMD_ERR ^ 0xFF; - while (t1 < t0 + STM32_RESYNC_TIMEOUT) { - p_err = port->write(port, buf, 2); - if (p_err != PORT_ERR_OK) { - usleep(500000); - time(&t1); - continue; - } - p_err = port->read(port, &ack, 1); - if (p_err != PORT_ERR_OK) { - time(&t1); - continue; - } - if (ack == STM32_NACK) - return STM32_ERR_OK; - time(&t1); - } - return STM32_ERR_UNKNOWN; -} - -/* - * some command receive reply frame with variable length, and length is - * embedded in reply frame itself. - * We can guess the length, but if we guess wrong the protocol gets out - * of sync. - * Use resync for frame oriented interfaces (e.g. I2C) and byte-by-byte - * read for byte oriented interfaces (e.g. UART). - * - * to run safely, data buffer should be allocated for 256+1 bytes - * - * len is value of the first byte in the frame. - */ -static stm32_err_t stm32_guess_len_cmd(const stm32_t *stm, uint8_t cmd, - uint8_t *data, unsigned int len) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - if (port->flags & PORT_BYTE) { - /* interface is UART-like */ - p_err = port->read(port, data, 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - len = data[0]; - p_err = port->read(port, data + 1, len + 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; - } - - p_err = port->read(port, data, len + 2); - if (p_err == PORT_ERR_OK && len == data[0]) - return STM32_ERR_OK; - if (p_err != PORT_ERR_OK) { - /* restart with only one byte */ - if (stm32_resync(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - p_err = port->read(port, data, 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - } - - fprintf(stderr, "Re sync (len = %d)\n", data[0]); - if (stm32_resync(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - len = data[0]; - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - p_err = port->read(port, data, len + 2); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; -} - -/* - * Some interface, e.g. UART, requires a specific init sequence to let STM32 - * autodetect the interface speed. - * The sequence is only required one time after reset. - * stm32flash has command line flag "-c" to prevent sending the init sequence - * in case it was already sent before. - * User can easily forget adding "-c". In this case the bootloader would - * interpret the init sequence as part of a command message, then waiting for - * the rest of the message blocking the interface. - * This function sends the init sequence and, in case of timeout, recovers - * the interface. - */ -static stm32_err_t stm32_send_init_seq(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - uint8_t byte, cmd = STM32_CMD_INIT; - - p_err = port->write(port, &cmd, 1); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send init to device\n"); - return STM32_ERR_UNKNOWN; - } - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_OK && byte == STM32_ACK) - return STM32_ERR_OK; - if (p_err == PORT_ERR_OK && byte == STM32_NACK) { - /* We could get error later, but let's continue, for now. */ - fprintf(stderr, - "Warning: the interface was not closed properly.\n"); - return STM32_ERR_OK; - } - if (p_err != PORT_ERR_TIMEDOUT) { - fprintf(stderr, "Failed to init device.\n"); - return STM32_ERR_UNKNOWN; - } - - /* - * Check if previous STM32_CMD_INIT was taken as first byte - * of a command. Send a new byte, we should get back a NACK. - */ - p_err = port->write(port, &cmd, 1); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send init to device\n"); - return STM32_ERR_UNKNOWN; - } - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_OK && byte == STM32_NACK) - return STM32_ERR_OK; - fprintf(stderr, "Failed to init device.\n"); - return STM32_ERR_UNKNOWN; -} - -/* find newer command by higher code */ -#define newer(prev, a) (((prev) == STM32_CMD_ERR) \ - ? (a) \ - : (((prev) > (a)) ? (prev) : (a))) - -stm32_t *stm32_init(struct port_interface *port, const char init) -{ - uint8_t len, val, buf[257]; - stm32_t *stm; - int i, new_cmds; - - stm = calloc(sizeof(stm32_t), 1); - stm->cmd = malloc(sizeof(stm32_cmd_t)); - memset(stm->cmd, STM32_CMD_ERR, sizeof(stm32_cmd_t)); - stm->port = port; - - if ((port->flags & PORT_CMD_INIT) && init) - if (stm32_send_init_seq(stm) != STM32_ERR_OK) - return NULL; - - /* get the version and read protection status */ - if (stm32_send_command(stm, STM32_CMD_GVR) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - /* From AN, only UART bootloader returns 3 bytes */ - len = (port->flags & PORT_GVR_ETX) ? 3 : 1; - if (port->read(port, buf, len) != PORT_ERR_OK) - return NULL; - stm->version = buf[0]; - stm->option1 = (port->flags & PORT_GVR_ETX) ? buf[1] : 0; - stm->option2 = (port->flags & PORT_GVR_ETX) ? buf[2] : 0; - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - /* get the bootloader information */ - len = STM32_CMD_GET_LENGTH; - if (port->cmd_get_reply) - for (i = 0; port->cmd_get_reply[i].length; i++) - if (stm->version == port->cmd_get_reply[i].version) { - len = port->cmd_get_reply[i].length; - break; - } - if (stm32_guess_len_cmd(stm, STM32_CMD_GET, buf, len) != STM32_ERR_OK) - return NULL; - len = buf[0] + 1; - stm->bl_version = buf[1]; - new_cmds = 0; - for (i = 1; i < len; i++) { - val = buf[i + 1]; - switch (val) { - case STM32_CMD_GET: - stm->cmd->get = val; break; - case STM32_CMD_GVR: - stm->cmd->gvr = val; break; - case STM32_CMD_GID: - stm->cmd->gid = val; break; - case STM32_CMD_RM: - stm->cmd->rm = val; break; - case STM32_CMD_GO: - stm->cmd->go = val; break; - case STM32_CMD_WM: - case STM32_CMD_WM_NS: - stm->cmd->wm = newer(stm->cmd->wm, val); - break; - case STM32_CMD_ER: - case STM32_CMD_EE: - case STM32_CMD_EE_NS: - stm->cmd->er = newer(stm->cmd->er, val); - break; - case STM32_CMD_WP: - case STM32_CMD_WP_NS: - stm->cmd->wp = newer(stm->cmd->wp, val); - break; - case STM32_CMD_UW: - case STM32_CMD_UW_NS: - stm->cmd->uw = newer(stm->cmd->uw, val); - break; - case STM32_CMD_RP: - case STM32_CMD_RP_NS: - stm->cmd->rp = newer(stm->cmd->rp, val); - break; - case STM32_CMD_UR: - case STM32_CMD_UR_NS: - stm->cmd->ur = newer(stm->cmd->ur, val); - break; - case STM32_CMD_CRC: - stm->cmd->crc = newer(stm->cmd->crc, val); - break; - default: - if (new_cmds++ == 0) - fprintf(stderr, - "GET returns unknown commands (0x%2x", - val); - else - fprintf(stderr, ", 0x%2x", val); - } - } - if (new_cmds) - fprintf(stderr, ")\n"); - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - if (stm->cmd->get == STM32_CMD_ERR - || stm->cmd->gvr == STM32_CMD_ERR - || stm->cmd->gid == STM32_CMD_ERR) { - fprintf(stderr, "Error: bootloader did not returned correct information from GET command\n"); - return NULL; - } - - /* get the device ID */ - if (stm32_guess_len_cmd(stm, stm->cmd->gid, buf, 1) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - len = buf[0] + 1; - if (len < 2) { - stm32_close(stm); - fprintf(stderr, "Only %d bytes sent in the PID, unknown/unsupported device\n", len); - return NULL; - } - stm->pid = (buf[1] << 8) | buf[2]; - if (len > 2) { - fprintf(stderr, "This bootloader returns %d extra bytes in PID:", len); - for (i = 2; i <= len ; i++) - fprintf(stderr, " %02x", buf[i]); - fprintf(stderr, "\n"); - } - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - stm->dev = devices; - while (stm->dev->id != 0x00 && stm->dev->id != stm->pid) - ++stm->dev; - - if (!stm->dev->id) { - fprintf(stderr, "Unknown/unsupported device (Device ID: 0x%03x)\n", stm->pid); - stm32_close(stm); - return NULL; - } - - return stm; -} - -void stm32_close(stm32_t *stm) -{ - if (stm) - free(stm->cmd); - free(stm); -} - -stm32_err_t stm32_read_memory(const stm32_t *stm, uint32_t address, - uint8_t data[], unsigned int len) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (!len) - return STM32_ERR_OK; - - if (len > 256) { - fprintf(stderr, "Error: READ length limit at 256 bytes\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->rm == STM32_CMD_ERR) { - fprintf(stderr, "Error: READ command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->rm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_send_command(stm, len - 1) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (port->read(port, data, len) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - return STM32_ERR_OK; -} - -stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, - const uint8_t data[], unsigned int len) -{ - struct port_interface *port = stm->port; - uint8_t cs, buf[256 + 2]; - unsigned int i, aligned_len; - stm32_err_t s_err; - - if (!len) - return STM32_ERR_OK; - - if (len > 256) { - fprintf(stderr, "Error: READ length limit at 256 bytes\n"); - return STM32_ERR_UNKNOWN; - } - - /* must be 32bit aligned */ - if (address & 0x3 || len & 0x3) { - fprintf(stderr, "Error: WRITE address and length must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->wm == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - /* send the address and checksum */ - if (stm32_send_command(stm, stm->cmd->wm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - aligned_len = (len + 3) & ~3; - cs = aligned_len - 1; - buf[0] = aligned_len - 1; - for (i = 0; i < len; i++) { - cs ^= data[i]; - buf[i + 1] = data[i]; - } - /* padding data */ - for (i = len; i < aligned_len; i++) { - cs ^= 0xFF; - buf[i + 1] = 0xFF; - } - buf[aligned_len + 1] = cs; - if (port->write(port, buf, aligned_len + 2) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_BLKWRITE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->wm != STM32_CMD_WM_NS) - stm32_warn_stretching("write"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_wunprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->uw == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE UNPROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->uw) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_WUNPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to WRITE UNPROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->uw != STM32_CMD_UW_NS) - stm32_warn_stretching("WRITE UNPROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_wprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->wp == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE PROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->wp) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_WPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to WRITE PROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->wp != STM32_CMD_WP_NS) - stm32_warn_stretching("WRITE PROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_runprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->ur == STM32_CMD_ERR) { - fprintf(stderr, "Error: READOUT UNPROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->ur) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to READOUT UNPROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->ur != STM32_CMD_UR_NS) - stm32_warn_stretching("READOUT UNPROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_readprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->rp == STM32_CMD_ERR) { - fprintf(stderr, "Error: READOUT PROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->rp) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_RPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to READOUT PROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->rp != STM32_CMD_RP_NS) - stm32_warn_stretching("READOUT PROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - port_err_t p_err; - - if (!pages) - return STM32_ERR_OK; - - if (stm->cmd->er == STM32_CMD_ERR) { - fprintf(stderr, "Error: ERASE command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->er) != STM32_ERR_OK) { - fprintf(stderr, "Can't initiate chip erase!\n"); - return STM32_ERR_UNKNOWN; - } - - /* The erase command reported by the bootloader is either 0x43, 0x44 or 0x45 */ - /* 0x44 is Extended Erase, a 2 byte based protocol and needs to be handled differently. */ - /* 0x45 is clock no-stretching version of Extended Erase for I2C port. */ - if (stm->cmd->er != STM32_CMD_ER) { - /* Not all chips using Extended Erase support mass erase */ - /* Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range */ - /* So if someone has not overridden the default, but uses one of these chips, take it out of */ - /* mass erase mode, so it will be done page by page. This maximum might not be correct either! */ - if (stm->pid == 0x416 && pages == 0xFF) - pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ - - if (pages == 0xFF) { - uint8_t buf[3]; - - /* 0xFFFF the magic number for mass erase */ - buf[0] = 0xFF; - buf[1] = 0xFF; - buf[2] = 0x00; /* checksum */ - if (port->write(port, buf, 3) != PORT_ERR_OK) { - fprintf(stderr, "Mass erase error.\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Mass erase failed. Try specifying the number of pages to be erased.\n"); - if (port->flags & PORT_STRETCH_W - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } - - uint16_t pg_num; - uint8_t pg_byte; - uint8_t cs = 0; - uint8_t *buf; - int i = 0; - - buf = malloc(2 + 2 * pages + 1); - if (!buf) - return STM32_ERR_UNKNOWN; - - /* Number of pages to be erased - 1, two bytes, MSB first */ - pg_byte = (pages - 1) >> 8; - buf[i++] = pg_byte; - cs ^= pg_byte; - pg_byte = (pages - 1) & 0xFF; - buf[i++] = pg_byte; - cs ^= pg_byte; - - for (pg_num = spage; pg_num < spage + pages; pg_num++) { - pg_byte = pg_num >> 8; - cs ^= pg_byte; - buf[i++] = pg_byte; - pg_byte = pg_num & 0xFF; - cs ^= pg_byte; - buf[i++] = pg_byte; - } - buf[i++] = cs; - p_err = port->write(port, buf, i); - free(buf); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Page-by-page erase error.\n"); - return STM32_ERR_UNKNOWN; - } - - s_err = stm32_get_ack_timeout(stm, pages * STM32_SECTERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Page-by-page erase failed. Check the maximum pages your device supports.\n"); - if (port->flags & PORT_STRETCH_W - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - - return STM32_ERR_OK; - } - - /* And now the regular erase (0x43) for all other chips */ - if (pages == 0xFF) { - s_err = stm32_send_command_timeout(stm, 0xFF, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } else { - uint8_t cs = 0; - uint8_t pg_num; - uint8_t *buf; - int i = 0; - - buf = malloc(1 + pages + 1); - if (!buf) - return STM32_ERR_UNKNOWN; - - buf[i++] = pages - 1; - cs ^= (pages-1); - for (pg_num = spage; pg_num < (pages + spage); pg_num++) { - buf[i++] = pg_num; - cs ^= pg_num; - } - buf[i++] = cs; - p_err = port->write(port, buf, i); - free(buf); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Erase failed.\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } -} - -static stm32_err_t stm32_run_raw_code(const stm32_t *stm, - uint32_t target_address, - const uint8_t *code, uint32_t code_size) -{ - uint32_t stack_le = le_u32(0x20002000); - uint32_t code_address_le = le_u32(target_address + 8); - uint32_t length = code_size + 8; - uint8_t *mem, *pos; - uint32_t address, w; - - /* Must be 32-bit aligned */ - if (target_address & 0x3) { - fprintf(stderr, "Error: code address must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - mem = malloc(length); - if (!mem) - return STM32_ERR_UNKNOWN; - - memcpy(mem, &stack_le, sizeof(uint32_t)); - memcpy(mem + 4, &code_address_le, sizeof(uint32_t)); - memcpy(mem + 8, code, code_size); - - pos = mem; - address = target_address; - while (length > 0) { - w = length > 256 ? 256 : length; - if (stm32_write_memory(stm, address, pos, w) != STM32_ERR_OK) { - free(mem); - return STM32_ERR_UNKNOWN; - } - - address += w; - pos += w; - length -= w; - } - - free(mem); - return stm32_go(stm, target_address); -} - -stm32_err_t stm32_go(const stm32_t *stm, uint32_t address) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (stm->cmd->go == STM32_CMD_ERR) { - fprintf(stderr, "Error: GO command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->go) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; -} - -stm32_err_t stm32_reset_device(const stm32_t *stm) -{ - uint32_t target_address = stm->dev->ram_start; - - return stm32_run_raw_code(stm, target_address, stm_reset_code, stm_reset_code_length); -} - -stm32_err_t stm32_crc_memory(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (address & 0x3 || length & 0x3) { - fprintf(stderr, "Start and end addresses must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->crc == STM32_CMD_ERR) { - fprintf(stderr, "Error: CRC command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->crc) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = length >> 24; - buf[1] = (length >> 16) & 0xFF; - buf[2] = (length >> 8) & 0xFF; - buf[3] = length & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (port->read(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (buf[4] != (buf[0] ^ buf[1] ^ buf[2] ^ buf[3])) - return STM32_ERR_UNKNOWN; - - *crc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; - return STM32_ERR_OK; -} - -/* - * CRC computed by STM32 is similar to the standard crc32_be() - * implemented, for example, in Linux kernel in ./lib/crc32.c - * But STM32 computes it on units of 32 bits word and swaps the - * bytes of the word before the computation. - * Due to byte swap, I cannot use any CRC available in existing - * libraries, so here is a simple not optimized implementation. - */ -#define CRCPOLY_BE 0x04c11db7 -#define CRC_MSBMASK 0x80000000 -#define CRC_INIT_VALUE 0xFFFFFFFF -uint32_t stm32_sw_crc(uint32_t crc, uint8_t *buf, unsigned int len) -{ - int i; - uint32_t data; - - if (len & 0x3) { - fprintf(stderr, "Buffer length must be multiple of 4 bytes\n"); - return 0; - } - - while (len) { - data = *buf++; - data |= *buf++ << 8; - data |= *buf++ << 16; - data |= *buf++ << 24; - len -= 4; - - crc ^= data; - - for (i = 0; i < 32; i++) - if (crc & CRC_MSBMASK) - crc = (crc << 1) ^ CRCPOLY_BE; - else - crc = (crc << 1); - } - return crc; -} - -stm32_err_t stm32_crc_wrapper(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc) -{ - uint8_t buf[256]; - uint32_t start, total_len, len, current_crc; - - if (address & 0x3 || length & 0x3) { - fprintf(stderr, "Start and end addresses must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->crc != STM32_CMD_ERR) - return stm32_crc_memory(stm, address, length, crc); - - start = address; - total_len = length; - current_crc = CRC_INIT_VALUE; - while (length) { - len = length > 256 ? 256 : length; - if (stm32_read_memory(stm, address, buf, len) != STM32_ERR_OK) { - fprintf(stderr, - "Failed to read memory at address 0x%08x, target write-protected?\n", - address); - return STM32_ERR_UNKNOWN; - } - current_crc = stm32_sw_crc(current_crc, buf, len); - length -= len; - address += len; - - fprintf(stderr, - "\rCRC address 0x%08x (%.2f%%) ", - address, - (100.0f / (float)total_len) * (float)(address - start) - ); - fflush(stderr); - } - fprintf(stderr, "Done.\n"); - *crc = current_crc; - return STM32_ERR_OK; -} diff --git a/linux64/src/stm32flash_serial/src/stm32.h b/linux64/src/stm32flash_serial/src/stm32.h deleted file mode 100644 index 1688fcb4b..000000000 --- a/linux64/src/stm32flash_serial/src/stm32.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _STM32_H -#define _STM32_H - -#include -#include "serial.h" - -#define STM32_MAX_RX_FRAME 256 /* cmd read memory */ -#define STM32_MAX_TX_FRAME (1 + 256 + 1) /* cmd write memory */ - -typedef enum { - STM32_ERR_OK = 0, - STM32_ERR_UNKNOWN, /* Generic error */ - STM32_ERR_NACK, - STM32_ERR_NO_CMD, /* Command not available in bootloader */ -} stm32_err_t; - -typedef struct stm32 stm32_t; -typedef struct stm32_cmd stm32_cmd_t; -typedef struct stm32_dev stm32_dev_t; - -struct stm32 { - const serial_t *serial; - struct port_interface *port; - uint8_t bl_version; - uint8_t version; - uint8_t option1, option2; - uint16_t pid; - stm32_cmd_t *cmd; - const stm32_dev_t *dev; -}; - -struct stm32_dev { - uint16_t id; - const char *name; - uint32_t ram_start, ram_end; - uint32_t fl_start, fl_end; - uint16_t fl_pps; // pages per sector - uint16_t fl_ps; // page size - uint32_t opt_start, opt_end; - uint32_t mem_start, mem_end; -}; - -stm32_t *stm32_init(struct port_interface *port, const char init); -void stm32_close(stm32_t *stm); -stm32_err_t stm32_read_memory(const stm32_t *stm, uint32_t address, - uint8_t data[], unsigned int len); -stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, - const uint8_t data[], unsigned int len); -stm32_err_t stm32_wunprot_memory(const stm32_t *stm); -stm32_err_t stm32_wprot_memory(const stm32_t *stm); -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, - uint8_t pages); -stm32_err_t stm32_go(const stm32_t *stm, uint32_t address); -stm32_err_t stm32_reset_device(const stm32_t *stm); -stm32_err_t stm32_readprot_memory(const stm32_t *stm); -stm32_err_t stm32_runprot_memory(const stm32_t *stm); -stm32_err_t stm32_crc_memory(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc); -stm32_err_t stm32_crc_wrapper(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc); -uint32_t stm32_sw_crc(uint32_t crc, uint8_t *buf, unsigned int len); - -#endif - diff --git a/linux64/src/stm32flash_serial/src/stm32flash.1 b/linux64/src/stm32flash_serial/src/stm32flash.1 deleted file mode 100644 index d37292f6a..000000000 --- a/linux64/src/stm32flash_serial/src/stm32flash.1 +++ /dev/null @@ -1,407 +0,0 @@ -.TH STM32FLASH 1 "2013\-11\-03" STM32FLASH "User command" -.SH NAME -stm32flash \- flashing utility for STM32 and STM32W through UART or I2C -.SH SYNOPSIS -.B stm32flash -.RB [ \-cfhjkouvCR ] -.RB [ \-a -.IR bus_address ] -.RB [ \-b -.IR baud_rate ] -.RB [ \-m -.IR serial_mode ] -.RB [ \-r -.IR filename ] -.RB [ \-w -.IR filename ] -.RB [ \-e -.IR num ] -.RB [ \-n -.IR count ] -.RB [ \-g -.IR address ] -.RB [ \-s -.IR start_page ] -.RB [ \-S -.IR address [: length ]] -.RB [ \-F -.IR RX_length [: TX_length ]] -.RB [ \-i -.IR GPIO_string ] -.RI [ tty_device -.R | -.IR i2c_device ] - -.SH DESCRIPTION -.B stm32flash -reads or writes the flash memory of STM32 and STM32W. - -It requires the STM32[W] to embed a bootloader compliant with ST -application note AN3155. -.B stm32flash -uses the serial port -.I tty_device -to interact with the bootloader of STM32[W]. - -.SH OPTIONS -.TP -.BI "\-a" " bus_address" -Specify address on bus for -.IR i2c_device . -This option is mandatory for I2C interface. - -.TP -.BI "\-b" " baud_rate" -Specify baud rate speed of -.IR tty_device . -Please notice that the ST bootloader can automatically detect the baud rate, -as explaned in chapter 2 of AN3155. -This option could be required together with option -.B "\-c" -or if following interaction with bootloader is expected. -Default is -.IR 57600 . - -.TP -.BI "\-m" " mode" -Specify the format of UART data. -.I mode -is a three characters long string where each character specifies, in -this strict order, character size, parity and stop bits. -The only values currenly used are -.I 8e1 -for standard STM32 bootloader and -.I 8n1 -for standard STM32W bootloader. -Default is -.IR 8e1 . - -.TP -.BI "\-r" " filename" -Specify to read the STM32[W] flash and write its content in -.I filename -in raw binary format (see below -.BR "FORMAT CONVERSION" ). - -.TP -.BI "\-w" " filename" -Specify to write the STM32[W] flash with the content of -.IR filename . -File format can be either raw binary or intel hex (see below -.BR "FORMAT CONVERSION" ). -The file format is automatically detected. -To by\-pass format detection and force binary mode (e.g. to -write an intel hex content in STM32[W] flash), use -.B \-f -option. - -.TP -.B \-u -Specify to disable write\-protection from STM32[W] flash. -The STM32[W] will be reset after this operation. - -.TP -.B \-j -Enable the flash read\-protection. - -.TP -.B \-k -Disable the flash read\-protection. - -.TP -.B \-o -Erase only. - -.TP -.BI "\-e" " num" -Specify to erase only -.I num -pages before writing the flash. Default is to erase the whole flash. With -.B \-e 0 -the flash would not be erased. - -.TP -.B \-v -Specify to verify flash content after write operation. - -.TP -.BI "\-n" " count" -Specify to retry failed writes up to -.I count -times. Default is 10 times. - -.TP -.BI "\-g" " address" -Specify address to start execution from (0 = flash start). - -.TP -.BI "\-s" " start_page" -Specify flash page offset (0 = flash start). - -.TP -.BI "\-S" " address" "[:" "length" "]" -Specify start address and optionally length for read/write/erase/crc operations. - -.TP -.BI "\-F" " RX_length" "[:" "TX_length" "]" -Specify the maximum frame size for the current interface. -Due to STM32 bootloader protocol, host will never handle frames bigger than -256 byte in RX or 258 byte in TX. -Due to current code, lowest limit in RX is 20 byte (to read a complete reply -of command GET). Minimum limit in TX is 5 byte, required by protocol. - -.TP -.B \-f -Force binary parser while reading file with -.BR "\-w" "." - -.TP -.B \-h -Show help. - -.TP -.B \-c -Specify to resume the existing UART connection and don't send initial -INIT sequence to detect baud rate. Baud rate must be kept the same as the -existing connection. This is useful if the reset fails. - -.TP -.BI "\-i" " GPIO_string" -Specify the GPIO sequences on the host to force STM32[W] to enter and -exit bootloader mode. GPIO can either be real GPIO connected from host to -STM32[W] beside the UART connection, or UART's modem signals used as -GPIO. (See below -.B BOOTLOADER GPIO SEQUENCE -for the format of -.I GPIO_string -and further explanation). - -.TP -.B \-C -Specify to compute CRC on memory content. -By default the CRC is computed on the whole flash content. -Use -.B "\-S" -to provide different memory address range. - -.TP -.B \-R -Specify to reset the device at exit. -This option is ignored if either -.BR "\-g" "," -.BR "\-j" "," -.B "\-k" -or -.B "\-u" -is also specified. - -.SH BOOTLOADER GPIO SEQUENCE -This feature is currently available on Linux host only. - -As explained in ST application note AN2606, after reset the STM32 will -execute either the application program in user flash or the bootloader, -depending on the level applied at specific pins of STM32 during reset. - -STM32 bootloader is automatically activated by configuring the pins -BOOT0="high" and BOOT1="low" and then by applying a reset. -Application program in user flash is activated by configuring the pin -BOOT0="low" (the level on BOOT1 is ignored) and then by applying a reset. - -When GPIO from host computer are connected to either configuration and -reset pins of STM32, -.B stm32flash -can control the host GPIO to reset STM32 and to force execution of -bootloader or execution of application program. - -The sequence of GPIO values to entry to and exit from bootloader mode is -provided with command line option -.B "\-i" -.IR "GPIO_string" . - -.PD 0 -The format of -.IR "GPIO_string" " is:" -.RS -GPIO_string = [entry sequence][:[exit sequence]] -.P -sequence = [\-]n[,sequence] -.RE -.P -In the above sequences, negative numbers correspond to GPIO at "low" level; -numbers without sign correspond to GPIO at "high" level. -The value "n" can either be the GPIO number on the host system or the -string "rts", "dtr" or "brk". The strings "rts" and "dtr" drive the -corresponding UART's modem lines RTS and DTR as GPIO. -The string "brk" forces the UART to send a BREAK sequence on TX line; -after BREAK the UART is returned in normal "non\-break" mode. -Note: the string "\-brk" has no effect and is ignored. -.PD - -.PD 0 -As example, let's suppose the following connection between host and STM32: -.IP \(bu 2 -host GPIO_3 connected to reset pin of STM32; -.IP \(bu 2 -host GPIO_4 connected to STM32 pin BOOT0; -.IP \(bu 2 -host GPIO_5 connected to STM32 pin BOOT1. -.PD -.P - -In this case, the sequence to enter in bootloader mode is: first put -GPIO_4="high" and GPIO_5="low"; then send reset pulse by GPIO_3="low" -followed by GPIO_3="high". -The corresponding string for -.I GPIO_string -is "4,\-5,\-3,3". - -To exit from bootloade and run the application program, the sequence is: -put GPIO_4="low"; then send reset pulse. -The corresponding string for -.I GPIO_string -is "\-4,\-3,3". - -The complete command line flag is "\-i 4,\-5,\-3,3:\-4,\-3,3". - -STM32W uses pad PA5 to select boot mode; if during reset PA5 is "low" then -STM32W will enter in bootloader mode; if PA5 is "high" it will execute the -program in flash. - -As example, supposing GPIO_3 connected to PA5 and GPIO_2 to STM32W's reset. -The command: -.PD 0 -.RS -stm32flash \-i \-3,\-2,2:3,\-2,2 /dev/ttyS0 -.RE -provides: -.IP \(bu 2 -entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high -.IP \(bu 2 -exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high -.PD - -.SH EXAMPLES -Get device information: -.RS -.PD 0 -.P -stm32flash /dev/ttyS0 -.PD -.RE - -Write with verify and then start execution: -.RS -.PD 0 -.P -stm32flash \-w filename \-v \-g 0x0 /dev/ttyS0 -.PD -.RE - -Read flash to file: -.RS -.PD 0 -.P -stm32flash \-r filename /dev/ttyS0 -.PD -.RE - -Start execution: -.RS -.PD 0 -.P -stm32flash \-g 0x0 /dev/ttyS0 -.PD -.RE - -Specify: -.PD 0 -.IP \(bu 2 -entry sequence: RTS=low, DTR=low, DTR=high -.IP \(bu 2 -exit sequence: RTS=high, DTR=low, DTR=high -.P -.RS -stm32flash \-i \-rts,\-dtr,dtr:rts,\-dtr,dtr /dev/ttyS0 -.PD -.RE - -.SH FORMAT CONVERSION -Flash images provided by ST or created with ST tools are often in file -format Motorola S\-Record. -Conversion between raw binary, intel hex and Motorola S\-Record can be -done through software package SRecord. - -.SH AUTHORS -The original software package -.B stm32flash -is written by -.I Geoffrey McRae -and is since 2012 maintained by -.IR "Tormod Volden " . - -Man page and extension to STM32W and I2C are written by -.IR "Antonio Borneo " . - -Please report any bugs at the project homepage -http://stm32flash.googlecode.com . - -.SH SEE ALSO -.BR "srec_cat" "(1)," " srec_intel" "(5)," " srec_motorola" "(5)." - -The communication protocol used by ST bootloader is documented in -following ST application notes, depending on communication port. -The current version of -.B stm32flash -only supports -.I UART -and -.I I2C -ports. -.PD 0 -.P -.IP \(bu 2 -AN3154: CAN protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/CD00264321.pdf -.RE - -.P -.IP \(bu 2 -AN3155: USART protocol used in the STM32(TM) bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/CD00264342.pdf -.RE - -.P -.IP \(bu 2 -AN4221: I2C protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/DM00072315.pdf -.RE - -.P -.IP \(bu 2 -AN4286: SPI protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/DM00081379.pdf -.RE - -.PD - - -Boot mode selection for STM32 is documented in ST application note -AN2606, available from the ST website: -.PD 0 -.P -http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf -.PD - -.SH LICENSE -.B stm32flash -is distributed under GNU GENERAL PUBLIC LICENSE Version 2. -Copy of the license is available within the source code in the file -.IR "gpl\-2.0.txt" . diff --git a/linux64/src/stm32flash_serial/src/utils.c b/linux64/src/stm32flash_serial/src/utils.c deleted file mode 100644 index 271bb3ed7..000000000 --- a/linux64/src/stm32flash_serial/src/utils.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include "utils.h" - -/* detect CPU endian */ -char cpu_le() { - const uint32_t cpu_le_test = 0x12345678; - return ((const unsigned char*)&cpu_le_test)[0] == 0x78; -} - -uint32_t be_u32(const uint32_t v) { - if (cpu_le()) - return ((v & 0xFF000000) >> 24) | - ((v & 0x00FF0000) >> 8) | - ((v & 0x0000FF00) << 8) | - ((v & 0x000000FF) << 24); - return v; -} - -uint32_t le_u32(const uint32_t v) { - if (!cpu_le()) - return ((v & 0xFF000000) >> 24) | - ((v & 0x00FF0000) >> 8) | - ((v & 0x0000FF00) << 8) | - ((v & 0x000000FF) << 24); - return v; -} diff --git a/linux64/src/stm32flash_serial/src/utils.h b/linux64/src/stm32flash_serial/src/utils.h deleted file mode 100644 index a8d37d2d5..000000000 --- a/linux64/src/stm32flash_serial/src/utils.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_UTILS -#define _H_UTILS - -#include - -char cpu_le(); -uint32_t be_u32(const uint32_t v); -uint32_t le_u32(const uint32_t v); - -#endif diff --git a/linux64/stm32flash/stm32flash b/linux64/stm32flash/stm32flash index 7e067aee0..f1a848ded 100755 Binary files a/linux64/stm32flash/stm32flash and b/linux64/stm32flash/stm32flash differ diff --git a/macosx/src/stm32flash_serial/src/AUTHORS b/macosx/src/stm32flash_serial/src/AUTHORS deleted file mode 100644 index d096f2205..000000000 --- a/macosx/src/stm32flash_serial/src/AUTHORS +++ /dev/null @@ -1,19 +0,0 @@ -Authors ordered by first contribution. - -Geoffrey McRae -Bret Olmsted -Tormod Volden -Jakob Malm -Reuben Dowle -Matthias Kubisch -Paul Fertser -Daniel Strnad -Jérémie Rapin -Christian Pointner -Mats Erik Andersson -Alexey Borovik -Antonio Borneo -Armin van der Togt -Brian Silverman -Georg Hofmann -Luis Rodrigues diff --git a/macosx/src/stm32flash_serial/src/Android.mk b/macosx/src/stm32flash_serial/src/Android.mk deleted file mode 100644 index 7be3d0018..000000000 --- a/macosx/src/stm32flash_serial/src/Android.mk +++ /dev/null @@ -1,20 +0,0 @@ -TOP_LOCAL_PATH := $(call my-dir) - -include $(call all-named-subdir-makefiles, parsers) - -LOCAL_PATH := $(TOP_LOCAL_PATH) - -include $(CLEAR_VARS) -LOCAL_MODULE := stm32flash -LOCAL_SRC_FILES := \ - dev_table.c \ - i2c.c \ - init.c \ - main.c \ - port.c \ - serial_common.c \ - serial_platform.c \ - stm32.c \ - utils.c -LOCAL_STATIC_LIBRARIES := libparsers -include $(BUILD_EXECUTABLE) diff --git a/macosx/src/stm32flash_serial/src/HOWTO b/macosx/src/stm32flash_serial/src/HOWTO deleted file mode 100644 index d8f32eb04..000000000 --- a/macosx/src/stm32flash_serial/src/HOWTO +++ /dev/null @@ -1,35 +0,0 @@ -Add new interfaces: -===================================================================== -Current version 0.4 supports the following interfaces: -- UART Windows (either "COMn" and "\\.\COMn"); -- UART posix/Linux (e.g. "/dev/ttyUSB0"); -- I2C Linux through standard driver "i2c-dev" (e.g. "/dev/i2c-n"). - -Starting from version 0.4, the back-end of stm32flash is modular and -ready to be expanded to support new interfaces. -I'm planning adding SPI on Linux through standard driver "spidev". -You are invited to contribute with more interfaces. - -To add a new interface you need to add a new file, populate the struct -port_interface (check at the end of files i2c.c, serial_posix.c and -serial_w32.c) and provide the relative functions to operate on the -interface: open/close, read/write, get_cfg_str and the optional gpio. -The include the new drive in Makefile and register the new struct -port_interface in file port.c in struct port_interface *ports[]. - -There are several USB-I2C adapter in the market, each providing its -own libraries to communicate with the I2C bus. -Could be interesting to provide as back-end a bridge between stm32flash -and such libraries (I have no plan on this item). - - -Add new STM32 devices: -===================================================================== -Add a new line in file dev_table.c, in table devices[]. -The fields of the table are listed in stm32.h, struct stm32_dev. - - -Cross compile on Linux host for Windows target with MinGW: -===================================================================== -I'm using a 64 bit Arch Linux machines, and I usually run: - make CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar diff --git a/macosx/src/stm32flash_serial/src/I2C.txt b/macosx/src/stm32flash_serial/src/I2C.txt deleted file mode 100644 index 4c05ff62d..000000000 --- a/macosx/src/stm32flash_serial/src/I2C.txt +++ /dev/null @@ -1,94 +0,0 @@ -About I2C back-end communication in stm32flash -========================================================================== - -Starting from version v0.4, beside the serial communication port, -stm32flash adds support for I2C port to talk with STM32 bootloader. - -The current I2C back-end supports only the API provided by Linux kernel -driver "i2c-dev", so only I2C controllers with Linux kernel driver can be -used. -In Linux source code, most of the drivers for I2C and SMBUS controllers -are in - ./drivers/i2c/busses/ -Only I2C is supported by STM32 bootloader, so check the section below -about SMBUS. -No I2C support for Windows is available in stm32flash v0.4. - -Thanks to the new modular back-end, stm32flash can be easily extended to -support new back-ends and API. Check HOWTO file in stm32flash source code -for details. - -In the market there are several USB-to-I2C dongles; most of them are not -supported by kernel drivers. Manufacturer provide proprietary userspace -libraries using not standardized API. -These API and dongles could be supported in feature versions. - -There are currently 3 versions of STM32 bootloader for I2C communications: -- v1.0 using I2C clock stretching synchronization between host and STM32; -- v1.1 superset of v1.0, adds non stretching commands; -- v1.2 superset of v1.1, adds CRC command and compatibility with i2cdetect. -Details in ST application note AN2606. -All the bootloaders above are tested and working with stm32flash. - - -SMBUS controllers -========================================================================== - -Almost 50% of the drivers in Linux source code folder - ./drivers/i2c/busses/ -are for controllers that "only" support SMBUS protocol. They can NOT -operate with STM32 bootloader. -To identify if your controller supports I2C, use command: - i2cdetect -F n -where "n" is the number of the I2C interface (e.g. n=3 for "/dev/i2c-3"). -Controllers that supports I2C will report - I2C yes -Controller that support both I2C and SMBUS are ok. - -If you are interested on details about SMBUS protocol, you can download -the current specs from - http://smbus.org/specs/smbus20.pdf -and you can read the files in Linux source code - ./Documentation/i2c/i2c-protocol - ./Documentation/i2c/smbus-protocol - - -About bootloader v1.0 -========================================================================== - -Version v1.0 can have issues with some I2C controllers due to use of clock -stretching during commands that require long operations, like flash erase -and programming. - -Clock stretching is a technique to synchronize host and I2C device. When -I2C device wants to force a delay in the communication, it push "low" the -I2C clock; the I2C controller detects it and waits until I2C clock returns -"high". -Most I2C controllers set a "timeout" for clock stretching, ranging from -few milli-seconds to seconds depending on specific HW or SW driver. - -It is possible that the timeout in your I2C controller is smaller than the -delay required for flash erase or programming. In this case the I2C -controller will timeout and report error to stm32flash. -There is no possibility for stm32flash to retry, so it can only signal the -error and exit. - -To by-pass the issue with bootloader v1.0 you can modify the kernel driver -of your I2C controller. Not an easy job, since every controller has its own -way to handle the timeout. - -In my case I'm using the I2C controller integrated in the VGA port of my -laptop HP EliteBook 8460p. I built the 0.25$ VGA-to-I2C adapter reported in - http://www.paintyourdragon.com/?p=43 -To change the timeout of the I2C controller I had to modify the kernel file - drivers/gpu/drm/radeon/radeon_i2c.c -line 969 -- i2c->bit.timeout = usecs_to_jiffies(2200); /* from VESA */ -+ i2c->bit.timeout = msecs_to_jiffies(5000); /* 5s for STM32 */ -and recompile it. -Then - $> modprobe i2c-dev - $> chmod 666 /dev/i2c-7 - #> stm32flash -a 0x39 /dev/i2c-7 - -2014-09-16 Antonio Borneo diff --git a/macosx/src/stm32flash_serial/src/Makefile b/macosx/src/stm32flash_serial/src/Makefile deleted file mode 100644 index 0328d5588..000000000 --- a/macosx/src/stm32flash_serial/src/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -PREFIX = /usr/local -CFLAGS += -Wall -g - -INSTALL = install - -OBJS = dev_table.o \ - i2c.o \ - init.o \ - main.o \ - port.o \ - serial_common.o \ - serial_platform.o \ - stm32.o \ - utils.o - -LIBOBJS = parsers/parsers.a - -all: stm32flash - -serial_platform.o: serial_posix.c serial_w32.c - -parsers/parsers.a: - cd parsers && $(MAKE) parsers.a - -stm32flash: $(OBJS) $(LIBOBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBOBJS) - -clean: - rm -f $(OBJS) stm32flash - cd parsers && $(MAKE) $@ - -install: all - $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin - $(INSTALL) -m 755 stm32flash $(DESTDIR)$(PREFIX)/bin - $(INSTALL) -d $(DESTDIR)$(PREFIX)/share/man/man1 - $(INSTALL) -m 644 stm32flash.1 $(DESTDIR)$(PREFIX)/share/man/man1 - -.PHONY: all clean install diff --git a/macosx/src/stm32flash_serial/src/TODO b/macosx/src/stm32flash_serial/src/TODO deleted file mode 100644 index 41df614ff..000000000 --- a/macosx/src/stm32flash_serial/src/TODO +++ /dev/null @@ -1,7 +0,0 @@ - -stm32: -- Add support for variable page size - -AUTHORS: -- Add contributors from Geoffrey's commits - diff --git a/macosx/src/stm32flash_serial/src/dev_table.c b/macosx/src/stm32flash_serial/src/dev_table.c deleted file mode 100644 index 399cd9d08..000000000 --- a/macosx/src/stm32flash_serial/src/dev_table.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "stm32.h" - -/* - * Device table, corresponds to the "Bootloader device-dependant parameters" - * table in ST document AN2606. - * Note that the option bytes upper range is inclusive! - */ -const stm32_dev_t devices[] = { - /* F0 */ - {0x440, "STM32F051xx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, - {0x444, "STM32F030/F031" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, - {0x445, "STM32F042xx" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, - {0x448, "STM32F072xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, - /* F1 */ - {0x412, "Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x410, "Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x414, "High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x420, "Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x428, "High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x418, "Connectivity line" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, - {0x430, "XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, - /* Note that F2 and F4 devices have sectors of different page sizes - and only the first sectors (of one page size) are included here */ - /* F2 */ - {0x411, "STM32F2xx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, - /* F3 */ - {0x432, "STM32F373/8" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x422, "F302xB/303xB/358" , 0x20001400, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x439, "STM32F302x4(6/8)" , 0x20001800, 0x20004000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x438, "F303x4/334/328" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - /* F4 */ - {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, - /* 0x419 is also used for STM32F429/39 but with other bootloader ID... */ - {0x419, "STM32F427/37" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - /* L0 */ - {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - /* L1 */ - {0x416, "L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x429, "L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x427, "L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, - {0x436, "L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - {0x437, "L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - /* These are not (yet) in AN2606: */ - {0x641, "Medium_Density PL" , 0x20000200, 0x00005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, - {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 1, 2048, 0, 0, 0, 0}, - {0x0} -}; diff --git a/macosx/src/stm32flash_serial/src/gpl-2.0.txt b/macosx/src/stm32flash_serial/src/gpl-2.0.txt deleted file mode 100644 index d159169d1..000000000 --- a/macosx/src/stm32flash_serial/src/gpl-2.0.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/macosx/src/stm32flash_serial/src/i2c.c b/macosx/src/stm32flash_serial/src/i2c.c deleted file mode 100644 index 10e6bb15a..000000000 --- a/macosx/src/stm32flash_serial/src/i2c.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - - -#if !defined(__linux__) - -static port_err_t i2c_open(struct port_interface *port, - struct port_options *ops) -{ - return PORT_ERR_NODEV; -} - -struct port_interface port_i2c = { - .name = "i2c", - .open = i2c_open, -}; - -#else - -#ifdef __ANDROID__ -#define I2C_SLAVE 0x0703 /* Use this slave address */ -#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */ -/* To determine what functionality is present */ -#define I2C_FUNC_I2C 0x00000001 -#else -#include -#include -#endif - -#include - -struct i2c_priv { - int fd; - int addr; -}; - -static port_err_t i2c_open(struct port_interface *port, - struct port_options *ops) -{ - struct i2c_priv *h; - int fd, addr, ret; - unsigned long funcs; - - /* 1. check device name match */ - if (strncmp(ops->device, "/dev/i2c-", strlen("/dev/i2c-"))) - return PORT_ERR_NODEV; - - /* 2. check options */ - addr = ops->bus_addr; - if (addr < 0x03 || addr > 0x77) { - fprintf(stderr, "I2C address out of range [0x03-0x77]\n"); - return PORT_ERR_UNKNOWN; - } - - /* 3. open it */ - h = calloc(sizeof(*h), 1); - if (h == NULL) { - fprintf(stderr, "End of memory\n"); - return PORT_ERR_UNKNOWN; - } - fd = open(ops->device, O_RDWR); - if (fd < 0) { - fprintf(stderr, "Unable to open special file \"%s\"\n", - ops->device); - free(h); - return PORT_ERR_UNKNOWN; - } - - /* 3.5. Check capabilities */ - ret = ioctl(fd, I2C_FUNCS, &funcs); - if (ret < 0) { - fprintf(stderr, "I2C ioctl(funcs) error %d\n", errno); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - if ((funcs & I2C_FUNC_I2C) == 0) { - fprintf(stderr, "Error: controller is not I2C, only SMBUS.\n"); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - - /* 4. set options */ - ret = ioctl(fd, I2C_SLAVE, addr); - if (ret < 0) { - fprintf(stderr, "I2C ioctl(slave) error %d\n", errno); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - - h->fd = fd; - h->addr = addr; - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t i2c_close(struct port_interface *port) -{ - struct i2c_priv *h; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - close(h->fd); - free(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t i2c_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - struct i2c_priv *h; - int ret; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - ret = read(h->fd, buf, nbyte); - if (ret != nbyte) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; -} - -static port_err_t i2c_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - struct i2c_priv *h; - int ret; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - ret = write(h->fd, buf, nbyte); - if (ret != nbyte) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; -} - -static port_err_t i2c_gpio(struct port_interface *port, serial_gpio_t n, - int level) -{ - return PORT_ERR_OK; -} - -static const char *i2c_get_cfg_str(struct port_interface *port) -{ - struct i2c_priv *h; - static char str[11]; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return "INVALID"; - snprintf(str, sizeof(str), "addr 0x%2x", h->addr); - return str; -} - -static struct varlen_cmd i2c_cmd_get_reply[] = { - {0x10, 11}, - {0x11, 17}, - {0x12, 18}, - { /* sentinel */ } -}; - -struct port_interface port_i2c = { - .name = "i2c", - .flags = PORT_STRETCH_W, - .open = i2c_open, - .close = i2c_close, - .read = i2c_read, - .write = i2c_write, - .gpio = i2c_gpio, - .cmd_get_reply = i2c_cmd_get_reply, - .get_cfg_str = i2c_get_cfg_str, -}; - -#endif diff --git a/macosx/src/stm32flash_serial/src/init.c b/macosx/src/stm32flash_serial/src/init.c deleted file mode 100644 index 77a571bd8..000000000 --- a/macosx/src/stm32flash_serial/src/init.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include "init.h" -#include "serial.h" -#include "stm32.h" -#include "port.h" - -struct gpio_list { - struct gpio_list *next; - int gpio; -}; - - -static int write_to(const char *filename, const char *value) -{ - int fd, ret; - - fd = open(filename, O_WRONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open file \"%s\"\n", filename); - return 0; - } - ret = write(fd, value, strlen(value)); - if (ret < 0) { - fprintf(stderr, "Error writing in file \"%s\"\n", filename); - close(fd); - return 0; - } - close(fd); - return 1; -} - -#if !defined(__linux__) -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) -{ - fprintf(stderr, "GPIO control only available in Linux\n"); - return 0; -} -#else -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) -{ - char num[16]; /* sized to carry MAX_INT */ - char file[48]; /* sized to carry longest filename */ - struct stat buf; - struct gpio_list *new; - int ret; - - sprintf(file, "/sys/class/gpio/gpio%d/direction", n); - ret = stat(file, &buf); - if (ret) { - /* file miss, GPIO not exported yet */ - sprintf(num, "%d", n); - ret = write_to("/sys/class/gpio/export", num); - if (!ret) - return 0; - ret = stat(file, &buf); - if (ret) { - fprintf(stderr, "GPIO %d not available\n", n); - return 0; - } - new = (struct gpio_list *)malloc(sizeof(struct gpio_list)); - if (new == NULL) { - fprintf(stderr, "Out of memory\n"); - return 0; - } - new->gpio = n; - new->next = *gpio_to_release; - *gpio_to_release = new; - } - - return write_to(file, level ? "high" : "low"); -} -#endif - -static int release_gpio(int n) -{ - char num[16]; /* sized to carry MAX_INT */ - - sprintf(num, "%d", n); - return write_to("/sys/class/gpio/unexport", num); -} - -static int gpio_sequence(struct port_interface *port, const char *s, size_t l) -{ - struct gpio_list *gpio_to_release = NULL, *to_free; - int ret, level, gpio; - - ret = 1; - while (ret == 1 && *s && l > 0) { - if (*s == '-') { - level = 0; - s++; - l--; - } else - level = 1; - - if (isdigit(*s)) { - gpio = atoi(s); - while (isdigit(*s)) { - s++; - l--; - } - } else if (!strncmp(s, "rts", 3)) { - gpio = -GPIO_RTS; - s += 3; - l -= 3; - } else if (!strncmp(s, "dtr", 3)) { - gpio = -GPIO_DTR; - s += 3; - l -= 3; - } else if (!strncmp(s, "brk", 3)) { - gpio = -GPIO_BRK; - s += 3; - l -= 3; - } else { - fprintf(stderr, "Character \'%c\' is not a digit\n", *s); - ret = 0; - break; - } - - if (*s && (l > 0)) { - if (*s == ',') { - s++; - l--; - } else { - fprintf(stderr, "Character \'%c\' is not a separator\n", *s); - ret = 0; - break; - } - } - if (gpio < 0) - ret = (port->gpio(port, -gpio, level) == PORT_ERR_OK); - else - ret = drive_gpio(gpio, level, &gpio_to_release); - usleep(100000); - } - - while (gpio_to_release) { - release_gpio(gpio_to_release->gpio); - to_free = gpio_to_release; - gpio_to_release = gpio_to_release->next; - free(to_free); - } - usleep(500000); - return ret; -} - -static int gpio_bl_entry(struct port_interface *port, const char *seq) -{ - char *s; - - if (seq == NULL || seq[0] == ':') - return 1; - - s = strchr(seq, ':'); - if (s == NULL) - return gpio_sequence(port, seq, strlen(seq)); - - return gpio_sequence(port, seq, s - seq); -} - -static int gpio_bl_exit(struct port_interface *port, const char *seq) -{ - char *s; - - if (seq == NULL) - return 1; - - s = strchr(seq, ':'); - if (s == NULL || s[1] == '\0') - return 1; - - return gpio_sequence(port, s + 1, strlen(s + 1)); -} - -int init_bl_entry(struct port_interface *port, const char *seq) -{ - if (seq) - return gpio_bl_entry(port, seq); - - return 1; -} - -int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq) -{ - if (seq) - return gpio_bl_exit(port, seq); - - if (stm32_reset_device(stm) != STM32_ERR_OK) - return 0; - return 1; -} diff --git a/macosx/src/stm32flash_serial/src/init.h b/macosx/src/stm32flash_serial/src/init.h deleted file mode 100644 index 6075b519b..000000000 --- a/macosx/src/stm32flash_serial/src/init.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _INIT_H -#define _INIT_H - -#include "stm32.h" -#include "port.h" - -int init_bl_entry(struct port_interface *port, const char *seq); -int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq); - -#endif diff --git a/macosx/src/stm32flash_serial/src/main.c b/macosx/src/stm32flash_serial/src/main.c deleted file mode 100644 index f081d6131..000000000 --- a/macosx/src/stm32flash_serial/src/main.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright 2010 Geoffrey McRae - Copyright 2011 Steve Markgraf - Copyright 2012 Tormod Volden - Copyright 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "init.h" -#include "utils.h" -#include "serial.h" -#include "stm32.h" -#include "parsers/parser.h" -#include "port.h" - -#include "parsers/binary.h" -#include "parsers/hex.h" - -#define VERSION "Arduino_STM32_0.9" - -/* device globals */ -stm32_t *stm = NULL; - -void *p_st = NULL; -parser_t *parser = NULL; - -/* settings */ -struct port_options port_opts = { - .device = NULL, - .baudRate = SERIAL_BAUD_57600, - .serial_mode = "8e1", - .bus_addr = 0, - .rx_frame_max = STM32_MAX_RX_FRAME, - .tx_frame_max = STM32_MAX_TX_FRAME, -}; -int rd = 0; -int wr = 0; -int wu = 0; -int rp = 0; -int ur = 0; -int eraseOnly = 0; -int crc = 0; -int npages = 0; -int spage = 0; -int no_erase = 0; -char verify = 0; -int retry = 10; -char exec_flag = 0; -uint32_t execute = 0; -char init_flag = 1; -char force_binary = 0; -char reset_flag = 0; -char *filename; -char *gpio_seq = NULL; -uint32_t start_addr = 0; -uint32_t readwrite_len = 0; - -/* functions */ -int parse_options(int argc, char *argv[]); -void show_help(char *name); - -static int is_addr_in_ram(uint32_t addr) -{ - return addr >= stm->dev->ram_start && addr < stm->dev->ram_end; -} - -static int is_addr_in_flash(uint32_t addr) -{ - return addr >= stm->dev->fl_start && addr < stm->dev->fl_end; -} - -static int flash_addr_to_page_floor(uint32_t addr) -{ - if (!is_addr_in_flash(addr)) - return 0; - - return (addr - stm->dev->fl_start) / stm->dev->fl_ps; -} - -static int flash_addr_to_page_ceil(uint32_t addr) -{ - if (!(addr >= stm->dev->fl_start && addr <= stm->dev->fl_end)) - return 0; - - return (addr + stm->dev->fl_ps - 1 - stm->dev->fl_start) - / stm->dev->fl_ps; -} - -static uint32_t flash_page_to_addr(int page) -{ - return stm->dev->fl_start + page * stm->dev->fl_ps; -} - -int main(int argc, char* argv[]) { - struct port_interface *port = NULL; - int ret = 1; - stm32_err_t s_err; - parser_err_t perr; - FILE *diag = stdout; - - fprintf(diag, "stm32flash " VERSION "\n\n"); - fprintf(diag, "http://github.com/rogerclarkmelbourne/arduino_stm32\n\n"); - if (parse_options(argc, argv) != 0) - goto close; - - if (rd && filename[0] == '-') { - diag = stderr; - } - - if (wr) { - /* first try hex */ - if (!force_binary) { - parser = &PARSER_HEX; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - } - - if (force_binary || (perr = parser->open(p_st, filename, 0)) != PARSER_ERR_OK) { - if (force_binary || perr == PARSER_ERR_INVALID_FILE) { - if (!force_binary) { - parser->close(p_st); - p_st = NULL; - } - - /* now try binary */ - parser = &PARSER_BINARY; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - perr = parser->open(p_st, filename, 0); - } - - /* if still have an error, fail */ - if (perr != PARSER_ERR_OK) { - fprintf(stderr, "%s ERROR: %s\n", parser->name, parser_errstr(perr)); - if (perr == PARSER_ERR_SYSTEM) perror(filename); - goto close; - } - } - - fprintf(diag, "Using Parser : %s\n", parser->name); - } else { - parser = &PARSER_BINARY; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - } - - if (port_open(&port_opts, &port) != PORT_ERR_OK) { - fprintf(stderr, "Failed to open port: %s\n", port_opts.device); - goto close; - } - - fprintf(diag, "Interface %s: %s\n", port->name, port->get_cfg_str(port)); - if (init_flag && init_bl_entry(port, gpio_seq) == 0) - goto close; - stm = stm32_init(port, init_flag); - if (!stm) - goto close; - - fprintf(diag, "Version : 0x%02x\n", stm->bl_version); - if (port->flags & PORT_GVR_ETX) { - fprintf(diag, "Option 1 : 0x%02x\n", stm->option1); - fprintf(diag, "Option 2 : 0x%02x\n", stm->option2); - } - fprintf(diag, "Device ID : 0x%04x (%s)\n", stm->pid, stm->dev->name); - fprintf(diag, "- RAM : %dKiB (%db reserved by bootloader)\n", (stm->dev->ram_end - 0x20000000) / 1024, stm->dev->ram_start - 0x20000000); - fprintf(diag, "- Flash : %dKiB (sector size: %dx%d)\n", (stm->dev->fl_end - stm->dev->fl_start ) / 1024, stm->dev->fl_pps, stm->dev->fl_ps); - fprintf(diag, "- Option RAM : %db\n", stm->dev->opt_end - stm->dev->opt_start + 1); - fprintf(diag, "- System RAM : %dKiB\n", (stm->dev->mem_end - stm->dev->mem_start) / 1024); - - uint8_t buffer[256]; - uint32_t addr, start, end; - unsigned int len; - int failed = 0; - int first_page, num_pages; - - /* - * Cleanup addresses: - * - * Starting from options - * start_addr, readwrite_len, spage, npages - * and using device memory size, compute - * start, end, first_page, num_pages - */ - if (start_addr || readwrite_len) { - start = start_addr; - - if (is_addr_in_flash(start)) - end = stm->dev->fl_end; - else { - no_erase = 1; - if (is_addr_in_ram(start)) - end = stm->dev->ram_end; - else - end = start + sizeof(uint32_t); - } - - if (readwrite_len && (end > start + readwrite_len)) - end = start + readwrite_len; - - first_page = flash_addr_to_page_floor(start); - if (!first_page && end == stm->dev->fl_end) - num_pages = 0xff; /* mass erase */ - else - num_pages = flash_addr_to_page_ceil(end) - first_page; - } else if (!spage && !npages) { - start = stm->dev->fl_start; - end = stm->dev->fl_end; - first_page = 0; - num_pages = 0xff; /* mass erase */ - } else { - first_page = spage; - start = flash_page_to_addr(first_page); - if (start > stm->dev->fl_end) { - fprintf(stderr, "Address range exceeds flash size.\n"); - goto close; - } - - if (npages) { - num_pages = npages; - end = flash_page_to_addr(first_page + num_pages); - if (end > stm->dev->fl_end) - end = stm->dev->fl_end; - } else { - end = stm->dev->fl_end; - num_pages = flash_addr_to_page_ceil(end) - first_page; - } - - if (!first_page && end == stm->dev->fl_end) - num_pages = 0xff; /* mass erase */ - } - - if (rd) { - unsigned int max_len = port_opts.rx_frame_max; - - fprintf(diag, "Memory read\n"); - - perr = parser->open(p_st, filename, 1); - if (perr != PARSER_ERR_OK) { - fprintf(stderr, "%s ERROR: %s\n", parser->name, parser_errstr(perr)); - if (perr == PARSER_ERR_SYSTEM) - perror(filename); - goto close; - } - - fflush(diag); - addr = start; - while(addr < end) { - uint32_t left = end - addr; - len = max_len > left ? left : max_len; - s_err = stm32_read_memory(stm, addr, buffer, len); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read memory at address 0x%08x, target write-protected?\n", addr); - goto close; - } - if (parser->write(p_st, buffer, len) != PARSER_ERR_OK) - { - fprintf(stderr, "Failed to write data to file\n"); - goto close; - } - addr += len; - - fprintf(diag, - "\rRead address 0x%08x (%.2f%%) ", - addr, - (100.0f / (float)(end - start)) * (float)(addr - start) - ); - fflush(diag); - } - fprintf(diag, "Done.\n"); - ret = 0; - goto close; - } else if (rp) { - fprintf(stdout, "Read-Protecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_readprot_memory(stm); - fprintf(stdout, "Done.\n"); - } else if (ur) { - fprintf(stdout, "Read-UnProtecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_runprot_memory(stm); - fprintf(stdout, "Done.\n"); - } else if (eraseOnly) { - ret = 0; - fprintf(stdout, "Erasing flash\n"); - - if (num_pages != 0xff && - (start != flash_page_to_addr(first_page) - || end != flash_page_to_addr(first_page + num_pages))) { - fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); - ret = 1; - goto close; - } - - s_err = stm32_erase_memory(stm, first_page, num_pages); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to erase memory\n"); - ret = 1; - goto close; - } - } else if (wu) { - fprintf(diag, "Write-unprotecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_wunprot_memory(stm); - fprintf(diag, "Done.\n"); - - } else if (wr) { - fprintf(diag, "Write to memory\n"); - - off_t offset = 0; - ssize_t r; - unsigned int size; - unsigned int max_wlen, max_rlen; - - max_wlen = port_opts.tx_frame_max - 2; /* skip len and crc */ - max_wlen &= ~3; /* 32 bit aligned */ - - max_rlen = port_opts.rx_frame_max; - max_rlen = max_rlen < max_wlen ? max_rlen : max_wlen; - - /* Assume data from stdin is whole device */ - if (filename[0] == '-' && filename[1] == '\0') - size = end - start; - else - size = parser->size(p_st); - - // TODO: It is possible to write to non-page boundaries, by reading out flash - // from partial pages and combining with the input data - // if ((start % stm->dev->fl_ps) != 0 || (end % stm->dev->fl_ps) != 0) { - // fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); - // goto close; - // } - - // TODO: If writes are not page aligned, we should probably read out existing flash - // contents first, so it can be preserved and combined with new data - if (!no_erase && num_pages) { - fprintf(diag, "Erasing memory\n"); - s_err = stm32_erase_memory(stm, first_page, num_pages); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to erase memory\n"); - goto close; - } - } - - fflush(diag); - addr = start; - while(addr < end && offset < size) { - uint32_t left = end - addr; - len = max_wlen > left ? left : max_wlen; - len = len > size - offset ? size - offset : len; - - if (parser->read(p_st, buffer, &len) != PARSER_ERR_OK) - goto close; - - if (len == 0) { - if (filename[0] == '-') { - break; - } else { - fprintf(stderr, "Failed to read input file\n"); - goto close; - } - } - - again: - s_err = stm32_write_memory(stm, addr, buffer, len); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to write memory at address 0x%08x\n", addr); - goto close; - } - - if (verify) { - uint8_t compare[len]; - unsigned int offset, rlen; - - offset = 0; - while (offset < len) { - rlen = len - offset; - rlen = rlen < max_rlen ? rlen : max_rlen; - s_err = stm32_read_memory(stm, addr + offset, compare + offset, rlen); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read memory at address 0x%08x\n", addr + offset); - goto close; - } - offset += rlen; - } - - for(r = 0; r < len; ++r) - if (buffer[r] != compare[r]) { - if (failed == retry) { - fprintf(stderr, "Failed to verify at address 0x%08x, expected 0x%02x and found 0x%02x\n", - (uint32_t)(addr + r), - buffer [r], - compare[r] - ); - goto close; - } - ++failed; - goto again; - } - - failed = 0; - } - - addr += len; - offset += len; - - fprintf(diag, - "\rWrote %saddress 0x%08x (%.2f%%) ", - verify ? "and verified " : "", - addr, - (100.0f / size) * offset - ); - fflush(diag); - - } - - fprintf(diag, "Done.\n"); - ret = 0; - goto close; - } else if (crc) { - uint32_t crc_val = 0; - - fprintf(diag, "CRC computation\n"); - - s_err = stm32_crc_wrapper(stm, start, end - start, &crc_val); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read CRC\n"); - goto close; - } - fprintf(diag, "CRC(0x%08x-0x%08x) = 0x%08x\n", start, end, - crc_val); - ret = 0; - goto close; - } else - ret = 0; - -close: - if (stm && exec_flag && ret == 0) { - if (execute == 0) - execute = stm->dev->fl_start; - - fprintf(diag, "\nStarting execution at address 0x%08x... ", execute); - fflush(diag); - if (stm32_go(stm, execute) == STM32_ERR_OK) { - reset_flag = 0; - fprintf(diag, "done.\n"); - } else - fprintf(diag, "failed.\n"); - } - - if (stm && reset_flag) { - fprintf(diag, "\nResetting device... "); - fflush(diag); - if (init_bl_exit(stm, port, gpio_seq)) - fprintf(diag, "done.\n"); - else fprintf(diag, "failed.\n"); - } - - if (p_st ) parser->close(p_st); - if (stm ) stm32_close (stm); - if (port) - port->close(port); - - fprintf(diag, "\n"); - return ret; -} - -int parse_options(int argc, char *argv[]) -{ - int c; - char *pLen; - - while ((c = getopt(argc, argv, "a:b:m:r:w:e:vn:g:jkfcChuos:S:F:i:R")) != -1) { - switch(c) { - case 'a': - port_opts.bus_addr = strtoul(optarg, NULL, 0); - break; - - case 'b': - port_opts.baudRate = serial_get_baud(strtoul(optarg, NULL, 0)); - if (port_opts.baudRate == SERIAL_BAUD_INVALID) { - serial_baud_t baudrate; - fprintf(stderr, "Invalid baud rate, valid options are:\n"); - for (baudrate = SERIAL_BAUD_1200; baudrate != SERIAL_BAUD_INVALID; ++baudrate) - fprintf(stderr, " %d\n", serial_get_baud_int(baudrate)); - return 1; - } - break; - - case 'm': - if (strlen(optarg) != 3 - || serial_get_bits(optarg) == SERIAL_BITS_INVALID - || serial_get_parity(optarg) == SERIAL_PARITY_INVALID - || serial_get_stopbit(optarg) == SERIAL_STOPBIT_INVALID) { - fprintf(stderr, "Invalid serial mode\n"); - return 1; - } - port_opts.serial_mode = optarg; - break; - - case 'r': - case 'w': - rd = rd || c == 'r'; - wr = wr || c == 'w'; - if (rd && wr) { - fprintf(stderr, "ERROR: Invalid options, can't read & write at the same time\n"); - return 1; - } - filename = optarg; - if (filename[0] == '-') { - force_binary = 1; - } - break; - case 'e': - if (readwrite_len || start_addr) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } - npages = strtoul(optarg, NULL, 0); - if (npages > 0xFF || npages < 0) { - fprintf(stderr, "ERROR: You need to specify a page count between 0 and 255"); - return 1; - } - if (!npages) - no_erase = 1; - break; - case 'u': - wu = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't write unprotect and read/write at the same time\n"); - return 1; - } - break; - - case 'j': - rp = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't read protect and read/write at the same time\n"); - return 1; - } - break; - - case 'k': - ur = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't read unprotect and read/write at the same time\n"); - return 1; - } - break; - - case 'o': - eraseOnly = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't erase-only and read/write at the same time\n"); - return 1; - } - break; - - case 'v': - verify = 1; - break; - - case 'n': - retry = strtoul(optarg, NULL, 0); - break; - - case 'g': - exec_flag = 1; - execute = strtoul(optarg, NULL, 0); - if (execute % 4 != 0) { - fprintf(stderr, "ERROR: Execution address must be word-aligned\n"); - return 1; - } - break; - case 's': - if (readwrite_len || start_addr) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } - spage = strtoul(optarg, NULL, 0); - break; - case 'S': - if (spage || npages) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } else { - start_addr = strtoul(optarg, &pLen, 0); - if (*pLen == ':') { - pLen++; - readwrite_len = strtoul(pLen, NULL, 0); - if (readwrite_len == 0) { - fprintf(stderr, "ERROR: Invalid options, can't specify zero length\n"); - return 1; - } - } - } - break; - case 'F': - port_opts.rx_frame_max = strtoul(optarg, &pLen, 0); - if (*pLen == ':') { - pLen++; - port_opts.tx_frame_max = strtoul(pLen, NULL, 0); - } - if (port_opts.rx_frame_max < 0 - || port_opts.tx_frame_max < 0) { - fprintf(stderr, "ERROR: Invalid negative value for option -F\n"); - return 1; - } - if (port_opts.rx_frame_max == 0) - port_opts.rx_frame_max = STM32_MAX_RX_FRAME; - if (port_opts.tx_frame_max == 0) - port_opts.tx_frame_max = STM32_MAX_TX_FRAME; - if (port_opts.rx_frame_max < 20 - || port_opts.tx_frame_max < 5) { - fprintf(stderr, "ERROR: current code cannot work with small frames.\n"); - fprintf(stderr, "min(RX) = 20, min(TX) = 5\n"); - return 1; - } - if (port_opts.rx_frame_max > STM32_MAX_RX_FRAME) { - fprintf(stderr, "WARNING: Ignore RX length in option -F\n"); - port_opts.rx_frame_max = STM32_MAX_RX_FRAME; - } - if (port_opts.tx_frame_max > STM32_MAX_TX_FRAME) { - fprintf(stderr, "WARNING: Ignore TX length in option -F\n"); - port_opts.tx_frame_max = STM32_MAX_TX_FRAME; - } - break; - case 'f': - force_binary = 1; - break; - - case 'c': - init_flag = 0; - break; - - case 'h': - show_help(argv[0]); - exit(0); - - case 'i': - gpio_seq = optarg; - break; - - case 'R': - reset_flag = 1; - break; - - case 'C': - crc = 1; - break; - } - } - - for (c = optind; c < argc; ++c) { - if (port_opts.device) { - fprintf(stderr, "ERROR: Invalid parameter specified\n"); - show_help(argv[0]); - return 1; - } - port_opts.device = argv[c]; - } - - if (port_opts.device == NULL) { - fprintf(stderr, "ERROR: Device not specified\n"); - show_help(argv[0]); - return 1; - } - - if (!wr && verify) { - fprintf(stderr, "ERROR: Invalid usage, -v is only valid when writing\n"); - show_help(argv[0]); - return 1; - } - - return 0; -} - -void show_help(char *name) { - fprintf(stderr, - "Usage: %s [-bvngfhc] [-[rw] filename] [tty_device | i2c_device]\n" - " -a bus_address Bus address (e.g. for I2C port)\n" - " -b rate Baud rate (default 57600)\n" - " -m mode Serial port mode (default 8e1)\n" - " -r filename Read flash to file (or - stdout)\n" - " -w filename Write flash from file (or - stdout)\n" - " -C Compute CRC of flash content\n" - " -u Disable the flash write-protection\n" - " -j Enable the flash read-protection\n" - " -k Disable the flash read-protection\n" - " -o Erase only\n" - " -e n Only erase n pages before writing the flash\n" - " -v Verify writes\n" - " -n count Retry failed writes up to count times (default 10)\n" - " -g address Start execution at specified address (0 = flash start)\n" - " -S address[:length] Specify start address and optionally length for\n" - " read/write/erase operations\n" - " -F RX_length[:TX_length] Specify the max length of RX and TX frame\n" - " -s start_page Flash at specified page (0 = flash start)\n" - " -f Force binary parser\n" - " -h Show this help\n" - " -c Resume the connection (don't send initial INIT)\n" - " *Baud rate must be kept the same as the first init*\n" - " This is useful if the reset fails\n" - " -i GPIO_string GPIO sequence to enter/exit bootloader mode\n" - " GPIO_string=[entry_seq][:[exit_seq]]\n" - " sequence=[-]n[,sequence]\n" - " -R Reset device at exit.\n" - "\n" - "Examples:\n" - " Get device information:\n" - " %s /dev/ttyS0\n" - " or:\n" - " %s /dev/i2c-0\n" - "\n" - " Write with verify and then start execution:\n" - " %s -w filename -v -g 0x0 /dev/ttyS0\n" - "\n" - " Read flash to file:\n" - " %s -r filename /dev/ttyS0\n" - "\n" - " Read 100 bytes of flash from 0x1000 to stdout:\n" - " %s -r - -S 0x1000:100 /dev/ttyS0\n" - "\n" - " Start execution:\n" - " %s -g 0x0 /dev/ttyS0\n" - "\n" - " GPIO sequence:\n" - " - entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high\n" - " - exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high\n" - " %s -i -3,-2,2:3,-2,2 /dev/ttyS0\n", - name, - name, - name, - name, - name, - name, - name, - name - ); -} - diff --git a/macosx/src/stm32flash_serial/src/parsers/Android.mk b/macosx/src/stm32flash_serial/src/parsers/Android.mk deleted file mode 100644 index afec18cd5..000000000 --- a/macosx/src/stm32flash_serial/src/parsers/Android.mk +++ /dev/null @@ -1,6 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := libparsers -LOCAL_SRC_FILES := binary.c hex.c -include $(BUILD_STATIC_LIBRARY) diff --git a/macosx/src/stm32flash_serial/src/parsers/Makefile b/macosx/src/stm32flash_serial/src/parsers/Makefile deleted file mode 100644 index bb7df1e02..000000000 --- a/macosx/src/stm32flash_serial/src/parsers/Makefile +++ /dev/null @@ -1,12 +0,0 @@ - -CFLAGS += -Wall -g - -all: parsers.a - -parsers.a: binary.o hex.o - $(AR) rc $@ binary.o hex.o - -clean: - rm -f *.o parsers.a - -.PHONY: all clean diff --git a/macosx/src/stm32flash_serial/src/parsers/binary.c b/macosx/src/stm32flash_serial/src/parsers/binary.c deleted file mode 100644 index f491952bb..000000000 --- a/macosx/src/stm32flash_serial/src/parsers/binary.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include - -#include "binary.h" - -typedef struct { - int fd; - char write; - struct stat stat; -} binary_t; - -void* binary_init() { - return calloc(sizeof(binary_t), 1); -} - -parser_err_t binary_open(void *storage, const char *filename, const char write) { - binary_t *st = storage; - if (write) { - if (filename[0] == '-') - st->fd = 1; - else - st->fd = open( - filename, -#ifndef __WIN32__ - O_WRONLY | O_CREAT | O_TRUNC, -#else - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, -#endif -#ifndef __WIN32__ - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH -#else - 0 -#endif - ); - st->stat.st_size = 0; - } else { - if (filename[0] == '-') { - st->fd = 0; - } else { - if (stat(filename, &st->stat) != 0) - return PARSER_ERR_INVALID_FILE; - st->fd = open(filename, -#ifndef __WIN32__ - O_RDONLY -#else - O_RDONLY | O_BINARY -#endif - ); - } - } - - st->write = write; - return st->fd == -1 ? PARSER_ERR_SYSTEM : PARSER_ERR_OK; -} - -parser_err_t binary_close(void *storage) { - binary_t *st = storage; - - if (st->fd) close(st->fd); - free(st); - return PARSER_ERR_OK; -} - -unsigned int binary_size(void *storage) { - binary_t *st = storage; - return st->stat.st_size; -} - -parser_err_t binary_read(void *storage, void *data, unsigned int *len) { - binary_t *st = storage; - unsigned int left = *len; - if (st->write) return PARSER_ERR_WRONLY; - - ssize_t r; - while(left > 0) { - r = read(st->fd, data, left); - /* If there is no data to read at all, return OK, but with zero read */ - if (r == 0 && left == *len) { - *len = 0; - return PARSER_ERR_OK; - } - if (r <= 0) return PARSER_ERR_SYSTEM; - left -= r; - data += r; - } - - *len = *len - left; - return PARSER_ERR_OK; -} - -parser_err_t binary_write(void *storage, void *data, unsigned int len) { - binary_t *st = storage; - if (!st->write) return PARSER_ERR_RDONLY; - - ssize_t r; - while(len > 0) { - r = write(st->fd, data, len); - if (r < 1) return PARSER_ERR_SYSTEM; - st->stat.st_size += r; - - len -= r; - data += r; - } - - return PARSER_ERR_OK; -} - -parser_t PARSER_BINARY = { - "Raw BINARY", - binary_init, - binary_open, - binary_close, - binary_size, - binary_read, - binary_write -}; - diff --git a/macosx/src/stm32flash_serial/src/parsers/binary.h b/macosx/src/stm32flash_serial/src/parsers/binary.h deleted file mode 100644 index d989acfa0..000000000 --- a/macosx/src/stm32flash_serial/src/parsers/binary.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _PARSER_BINARY_H -#define _PARSER_BINARY_H - -#include "parser.h" - -extern parser_t PARSER_BINARY; -#endif diff --git a/macosx/src/stm32flash_serial/src/parsers/hex.c b/macosx/src/stm32flash_serial/src/parsers/hex.c deleted file mode 100644 index 3baf85623..000000000 --- a/macosx/src/stm32flash_serial/src/parsers/hex.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include - -#include "hex.h" -#include "../utils.h" - -typedef struct { - size_t data_len, offset; - uint8_t *data; - uint8_t base; -} hex_t; - -void* hex_init() { - return calloc(sizeof(hex_t), 1); -} - -parser_err_t hex_open(void *storage, const char *filename, const char write) { - hex_t *st = storage; - if (write) { - return PARSER_ERR_RDONLY; - } else { - char mark; - int i, fd; - uint8_t checksum; - unsigned int c; - uint32_t base = 0; - unsigned int last_address = 0x0; - - fd = open(filename, O_RDONLY); - if (fd < 0) - return PARSER_ERR_SYSTEM; - - /* read in the file */ - - while(read(fd, &mark, 1) != 0) { - if (mark == '\n' || mark == '\r') continue; - if (mark != ':') - return PARSER_ERR_INVALID_FILE; - - char buffer[9]; - unsigned int reclen, address, type; - uint8_t *record = NULL; - - /* get the reclen, address, and type */ - buffer[8] = 0; - if (read(fd, &buffer, 8) != 8) return PARSER_ERR_INVALID_FILE; - if (sscanf(buffer, "%2x%4x%2x", &reclen, &address, &type) != 3) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* setup the checksum */ - checksum = - reclen + - ((address & 0xFF00) >> 8) + - ((address & 0x00FF) >> 0) + - type; - - switch(type) { - /* data record */ - case 0: - c = address - last_address; - st->data = realloc(st->data, st->data_len + c + reclen); - - /* if there is a gap, set it to 0xff and increment the length */ - if (c > 0) { - memset(&st->data[st->data_len], 0xff, c); - st->data_len += c; - } - - last_address = address + reclen; - record = &st->data[st->data_len]; - st->data_len += reclen; - break; - - /* extended segment address record */ - case 2: - base = 0; - break; - - /* extended linear address record */ - case 4: - base = address; - break; - } - - buffer[2] = 0; - for(i = 0; i < reclen; ++i) { - if (read(fd, &buffer, 2) != 2 || sscanf(buffer, "%2x", &c) != 1) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* add the byte to the checksum */ - checksum += c; - - switch(type) { - case 0: - if (record != NULL) { - record[i] = c; - } else { - return PARSER_ERR_INVALID_FILE; - } - break; - - case 2: - case 4: - base = (base << 8) | c; - break; - } - } - - /* read, scan, and verify the checksum */ - if ( - read(fd, &buffer, 2 ) != 2 || - sscanf(buffer, "%2x", &c) != 1 || - (uint8_t)(checksum + c) != 0x00 - ) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - switch(type) { - /* EOF */ - case 1: - close(fd); - return PARSER_ERR_OK; - - /* address record */ - case 2: base = base << 4; - case 4: base = be_u32(base); - /* Reset last_address since our base changed */ - last_address = 0; - - if (st->base == 0) { - st->base = base; - break; - } - - /* we cant cope with files out of order */ - if (base < st->base) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* if there is a gap, enlarge and fill with zeros */ - unsigned int len = base - st->base; - if (len > st->data_len) { - st->data = realloc(st->data, len); - memset(&st->data[st->data_len], 0, len - st->data_len); - st->data_len = len; - } - break; - } - } - - close(fd); - return PARSER_ERR_OK; - } -} - -parser_err_t hex_close(void *storage) { - hex_t *st = storage; - if (st) free(st->data); - free(st); - return PARSER_ERR_OK; -} - -unsigned int hex_size(void *storage) { - hex_t *st = storage; - return st->data_len; -} - -parser_err_t hex_read(void *storage, void *data, unsigned int *len) { - hex_t *st = storage; - unsigned int left = st->data_len - st->offset; - unsigned int get = left > *len ? *len : left; - - memcpy(data, &st->data[st->offset], get); - st->offset += get; - - *len = get; - return PARSER_ERR_OK; -} - -parser_err_t hex_write(void *storage, void *data, unsigned int len) { - return PARSER_ERR_RDONLY; -} - -parser_t PARSER_HEX = { - "Intel HEX", - hex_init, - hex_open, - hex_close, - hex_size, - hex_read, - hex_write -}; - diff --git a/macosx/src/stm32flash_serial/src/parsers/hex.h b/macosx/src/stm32flash_serial/src/parsers/hex.h deleted file mode 100644 index 02413c9c9..000000000 --- a/macosx/src/stm32flash_serial/src/parsers/hex.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _PARSER_HEX_H -#define _PARSER_HEX_H - -#include "parser.h" - -extern parser_t PARSER_HEX; -#endif diff --git a/macosx/src/stm32flash_serial/src/parsers/parser.h b/macosx/src/stm32flash_serial/src/parsers/parser.h deleted file mode 100644 index c2fae3cf8..000000000 --- a/macosx/src/stm32flash_serial/src/parsers/parser.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_PARSER -#define _H_PARSER - -enum parser_err { - PARSER_ERR_OK, - PARSER_ERR_SYSTEM, - PARSER_ERR_INVALID_FILE, - PARSER_ERR_WRONLY, - PARSER_ERR_RDONLY -}; -typedef enum parser_err parser_err_t; - -struct parser { - const char *name; - void* (*init )(); /* initialise the parser */ - parser_err_t (*open )(void *storage, const char *filename, const char write); /* open the file for read|write */ - parser_err_t (*close)(void *storage); /* close and free the parser */ - unsigned int (*size )(void *storage); /* get the total data size */ - parser_err_t (*read )(void *storage, void *data, unsigned int *len); /* read a block of data */ - parser_err_t (*write)(void *storage, void *data, unsigned int len); /* write a block of data */ -}; -typedef struct parser parser_t; - -static inline const char* parser_errstr(parser_err_t err) { - switch(err) { - case PARSER_ERR_OK : return "OK"; - case PARSER_ERR_SYSTEM : return "System Error"; - case PARSER_ERR_INVALID_FILE: return "Invalid File"; - case PARSER_ERR_WRONLY : return "Parser can only write"; - case PARSER_ERR_RDONLY : return "Parser can only read"; - default: - return "Unknown Error"; - } -} - -#endif diff --git a/macosx/src/stm32flash_serial/src/port.c b/macosx/src/stm32flash_serial/src/port.c deleted file mode 100644 index 08e58cc34..000000000 --- a/macosx/src/stm32flash_serial/src/port.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include "serial.h" -#include "port.h" - - -extern struct port_interface port_serial; -extern struct port_interface port_i2c; - -static struct port_interface *ports[] = { - &port_serial, - &port_i2c, - NULL, -}; - - -port_err_t port_open(struct port_options *ops, struct port_interface **outport) -{ - int ret; - static struct port_interface **port; - - for (port = ports; *port; port++) { - ret = (*port)->open(*port, ops); - if (ret == PORT_ERR_NODEV) - continue; - if (ret == PORT_ERR_OK) - break; - fprintf(stderr, "Error probing interface \"%s\"\n", - (*port)->name); - } - if (*port == NULL) { - fprintf(stderr, "Cannot handle device \"%s\"\n", - ops->device); - return PORT_ERR_UNKNOWN; - } - - *outport = *port; - return PORT_ERR_OK; -} diff --git a/macosx/src/stm32flash_serial/src/port.h b/macosx/src/stm32flash_serial/src/port.h deleted file mode 100644 index 290f03496..000000000 --- a/macosx/src/stm32flash_serial/src/port.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_PORT -#define _H_PORT - -typedef enum { - PORT_ERR_OK = 0, - PORT_ERR_NODEV, /* No such device */ - PORT_ERR_TIMEDOUT, /* Operation timed out */ - PORT_ERR_UNKNOWN, -} port_err_t; - -/* flags */ -#define PORT_BYTE (1 << 0) /* byte (not frame) oriented */ -#define PORT_GVR_ETX (1 << 1) /* cmd GVR returns protection status */ -#define PORT_CMD_INIT (1 << 2) /* use INIT cmd to autodetect speed */ -#define PORT_RETRY (1 << 3) /* allowed read() retry after timeout */ -#define PORT_STRETCH_W (1 << 4) /* warning for no-stretching commands */ - -/* all options and flags used to open and configure an interface */ -struct port_options { - const char *device; - serial_baud_t baudRate; - const char *serial_mode; - int bus_addr; - int rx_frame_max; - int tx_frame_max; -}; - -/* - * Specify the length of reply for command GET - * This is helpful for frame-oriented protocols, e.g. i2c, to avoid time - * consuming try-fail-timeout-retry operation. - * On byte-oriented protocols, i.e. UART, this information would be skipped - * after read the first byte, so not needed. - */ -struct varlen_cmd { - uint8_t version; - uint8_t length; -}; - -struct port_interface { - const char *name; - unsigned flags; - port_err_t (*open)(struct port_interface *port, struct port_options *ops); - port_err_t (*close)(struct port_interface *port); - port_err_t (*read)(struct port_interface *port, void *buf, size_t nbyte); - port_err_t (*write)(struct port_interface *port, void *buf, size_t nbyte); - port_err_t (*gpio)(struct port_interface *port, serial_gpio_t n, int level); - const char *(*get_cfg_str)(struct port_interface *port); - struct varlen_cmd *cmd_get_reply; - void *private; -}; - -port_err_t port_open(struct port_options *ops, struct port_interface **outport); - -#endif diff --git a/macosx/src/stm32flash_serial/src/protocol.txt b/macosx/src/stm32flash_serial/src/protocol.txt deleted file mode 100644 index 039109908..000000000 --- a/macosx/src/stm32flash_serial/src/protocol.txt +++ /dev/null @@ -1,19 +0,0 @@ -The communication protocol used by ST bootloader is documented in following ST -application notes, depending on communication port. - -In current version of stm32flash are supported only UART and I2C ports. - -* AN3154: CAN protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/CD00264321.pdf - -* AN3155: USART protocol used in the STM32(TM) bootloader - http://www.st.com/web/en/resource/technical/document/application_note/CD00264342.pdf - -* AN4221: I2C protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/DM00072315.pdf - -* AN4286: SPI protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/DM00081379.pdf - -Boot mode selection for STM32 is documented in ST application note AN2606, available in ST website: - http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf diff --git a/macosx/src/stm32flash_serial/src/serial.h b/macosx/src/stm32flash_serial/src/serial.h deleted file mode 100644 index 227ba163b..000000000 --- a/macosx/src/stm32flash_serial/src/serial.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _SERIAL_H -#define _SERIAL_H - -typedef struct serial serial_t; - -typedef enum { - SERIAL_PARITY_NONE, - SERIAL_PARITY_EVEN, - SERIAL_PARITY_ODD, - - SERIAL_PARITY_INVALID -} serial_parity_t; - -typedef enum { - SERIAL_BITS_5, - SERIAL_BITS_6, - SERIAL_BITS_7, - SERIAL_BITS_8, - - SERIAL_BITS_INVALID -} serial_bits_t; - -typedef enum { - SERIAL_BAUD_1200, - SERIAL_BAUD_1800, - SERIAL_BAUD_2400, - SERIAL_BAUD_4800, - SERIAL_BAUD_9600, - SERIAL_BAUD_19200, - SERIAL_BAUD_38400, - SERIAL_BAUD_57600, - SERIAL_BAUD_115200, - SERIAL_BAUD_128000, - SERIAL_BAUD_230400, - SERIAL_BAUD_256000, - SERIAL_BAUD_460800, - SERIAL_BAUD_500000, - SERIAL_BAUD_576000, - SERIAL_BAUD_921600, - SERIAL_BAUD_1000000, - SERIAL_BAUD_1500000, - SERIAL_BAUD_2000000, - - SERIAL_BAUD_INVALID -} serial_baud_t; - -typedef enum { - SERIAL_STOPBIT_1, - SERIAL_STOPBIT_2, - - SERIAL_STOPBIT_INVALID -} serial_stopbit_t; - -typedef enum { - GPIO_RTS = 1, - GPIO_DTR, - GPIO_BRK, -} serial_gpio_t; - -/* common helper functions */ -serial_baud_t serial_get_baud(const unsigned int baud); -unsigned int serial_get_baud_int(const serial_baud_t baud); -serial_bits_t serial_get_bits(const char *mode); -unsigned int serial_get_bits_int(const serial_bits_t bits); -serial_parity_t serial_get_parity(const char *mode); -char serial_get_parity_str(const serial_parity_t parity); -serial_stopbit_t serial_get_stopbit(const char *mode); -unsigned int serial_get_stopbit_int(const serial_stopbit_t stopbit); - -#endif diff --git a/macosx/src/stm32flash_serial/src/serial_common.c b/macosx/src/stm32flash_serial/src/serial_common.c deleted file mode 100644 index 43e48e1ac..000000000 --- a/macosx/src/stm32flash_serial/src/serial_common.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "serial.h" - -serial_baud_t serial_get_baud(const unsigned int baud) { - switch(baud) { - case 1200: return SERIAL_BAUD_1200 ; - case 1800: return SERIAL_BAUD_1800 ; - case 2400: return SERIAL_BAUD_2400 ; - case 4800: return SERIAL_BAUD_4800 ; - case 9600: return SERIAL_BAUD_9600 ; - case 19200: return SERIAL_BAUD_19200 ; - case 38400: return SERIAL_BAUD_38400 ; - case 57600: return SERIAL_BAUD_57600 ; - case 115200: return SERIAL_BAUD_115200; - case 128000: return SERIAL_BAUD_128000; - case 230400: return SERIAL_BAUD_230400; - case 256000: return SERIAL_BAUD_256000; - case 460800: return SERIAL_BAUD_460800; - case 500000: return SERIAL_BAUD_500000; - case 576000: return SERIAL_BAUD_576000; - case 921600: return SERIAL_BAUD_921600; - case 1000000: return SERIAL_BAUD_1000000; - case 1500000: return SERIAL_BAUD_1500000; - case 2000000: return SERIAL_BAUD_2000000; - - default: - return SERIAL_BAUD_INVALID; - } -} - -unsigned int serial_get_baud_int(const serial_baud_t baud) { - switch(baud) { - case SERIAL_BAUD_1200 : return 1200 ; - case SERIAL_BAUD_1800 : return 1800 ; - case SERIAL_BAUD_2400 : return 2400 ; - case SERIAL_BAUD_4800 : return 4800 ; - case SERIAL_BAUD_9600 : return 9600 ; - case SERIAL_BAUD_19200 : return 19200 ; - case SERIAL_BAUD_38400 : return 38400 ; - case SERIAL_BAUD_57600 : return 57600 ; - case SERIAL_BAUD_115200: return 115200; - case SERIAL_BAUD_128000: return 128000; - case SERIAL_BAUD_230400: return 230400; - case SERIAL_BAUD_256000: return 256000; - case SERIAL_BAUD_460800: return 460800; - case SERIAL_BAUD_500000: return 500000; - case SERIAL_BAUD_576000: return 576000; - case SERIAL_BAUD_921600: return 921600; - case SERIAL_BAUD_1000000: return 1000000; - case SERIAL_BAUD_1500000: return 1500000; - case SERIAL_BAUD_2000000: return 2000000; - - case SERIAL_BAUD_INVALID: - default: - return 0; - } -} - -serial_bits_t serial_get_bits(const char *mode) { - if (!mode) - return SERIAL_BITS_INVALID; - switch(mode[0]) { - case '5': return SERIAL_BITS_5; - case '6': return SERIAL_BITS_6; - case '7': return SERIAL_BITS_7; - case '8': return SERIAL_BITS_8; - - default: - return SERIAL_BITS_INVALID; - } -} - -unsigned int serial_get_bits_int(const serial_bits_t bits) { - switch(bits) { - case SERIAL_BITS_5: return 5; - case SERIAL_BITS_6: return 6; - case SERIAL_BITS_7: return 7; - case SERIAL_BITS_8: return 8; - - default: - return 0; - } -} - -serial_parity_t serial_get_parity(const char *mode) { - if (!mode || !mode[0]) - return SERIAL_PARITY_INVALID; - switch(mode[1]) { - case 'N': - case 'n': - return SERIAL_PARITY_NONE; - case 'E': - case 'e': - return SERIAL_PARITY_EVEN; - case 'O': - case 'o': - return SERIAL_PARITY_ODD; - - default: - return SERIAL_PARITY_INVALID; - } -} - -char serial_get_parity_str(const serial_parity_t parity) { - switch(parity) { - case SERIAL_PARITY_NONE: return 'N'; - case SERIAL_PARITY_EVEN: return 'E'; - case SERIAL_PARITY_ODD : return 'O'; - - default: - return ' '; - } -} - -serial_stopbit_t serial_get_stopbit(const char *mode) { - if (!mode || !mode[0] || !mode[1]) - return SERIAL_STOPBIT_INVALID; - switch(mode[2]) { - case '1': return SERIAL_STOPBIT_1; - case '2': return SERIAL_STOPBIT_2; - - default: - return SERIAL_STOPBIT_INVALID; - } -} - -unsigned int serial_get_stopbit_int(const serial_stopbit_t stopbit) { - switch(stopbit) { - case SERIAL_STOPBIT_1: return 1; - case SERIAL_STOPBIT_2: return 2; - - default: - return 0; - } -} - diff --git a/macosx/src/stm32flash_serial/src/serial_platform.c b/macosx/src/stm32flash_serial/src/serial_platform.c deleted file mode 100644 index 98e256921..000000000 --- a/macosx/src/stm32flash_serial/src/serial_platform.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined(__WIN32__) || defined(__CYGWIN__) -# include "serial_w32.c" -#else -# include "serial_posix.c" -#endif diff --git a/macosx/src/stm32flash_serial/src/serial_posix.c b/macosx/src/stm32flash_serial/src/serial_posix.c deleted file mode 100644 index 284b35b20..000000000 --- a/macosx/src/stm32flash_serial/src/serial_posix.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - -struct serial { - int fd; - struct termios oldtio; - struct termios newtio; - char setup_str[11]; -}; - -static serial_t *serial_open(const char *device) -{ - serial_t *h = calloc(sizeof(serial_t), 1); - - h->fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); - if (h->fd < 0) { - free(h); - return NULL; - } - fcntl(h->fd, F_SETFL, 0); - - tcgetattr(h->fd, &h->oldtio); - tcgetattr(h->fd, &h->newtio); - - return h; -} - -static void serial_flush(const serial_t *h) -{ - tcflush(h->fd, TCIFLUSH); -} - -static void serial_close(serial_t *h) -{ - serial_flush(h); - tcsetattr(h->fd, TCSANOW, &h->oldtio); - close(h->fd); - free(h); -} - -static port_err_t serial_setup(serial_t *h, const serial_baud_t baud, - const serial_bits_t bits, - const serial_parity_t parity, - const serial_stopbit_t stopbit) -{ - speed_t port_baud; - tcflag_t port_bits; - tcflag_t port_parity; - tcflag_t port_stop; - struct termios settings; - - switch (baud) { - case SERIAL_BAUD_1200: port_baud = B1200; break; - case SERIAL_BAUD_1800: port_baud = B1800; break; - case SERIAL_BAUD_2400: port_baud = B2400; break; - case SERIAL_BAUD_4800: port_baud = B4800; break; - case SERIAL_BAUD_9600: port_baud = B9600; break; - case SERIAL_BAUD_19200: port_baud = B19200; break; - case SERIAL_BAUD_38400: port_baud = B38400; break; - case SERIAL_BAUD_57600: port_baud = B57600; break; - case SERIAL_BAUD_115200: port_baud = B115200; break; - case SERIAL_BAUD_230400: port_baud = B230400; break; -#ifdef B460800 - case SERIAL_BAUD_460800: port_baud = B460800; break; -#endif /* B460800 */ -#ifdef B921600 - case SERIAL_BAUD_921600: port_baud = B921600; break; -#endif /* B921600 */ -#ifdef B500000 - case SERIAL_BAUD_500000: port_baud = B500000; break; -#endif /* B500000 */ -#ifdef B576000 - case SERIAL_BAUD_576000: port_baud = B576000; break; -#endif /* B576000 */ -#ifdef B1000000 - case SERIAL_BAUD_1000000: port_baud = B1000000; break; -#endif /* B1000000 */ -#ifdef B1500000 - case SERIAL_BAUD_1500000: port_baud = B1500000; break; -#endif /* B1500000 */ -#ifdef B2000000 - case SERIAL_BAUD_2000000: port_baud = B2000000; break; -#endif /* B2000000 */ - - case SERIAL_BAUD_INVALID: - default: - return PORT_ERR_UNKNOWN; - } - - switch (bits) { - case SERIAL_BITS_5: port_bits = CS5; break; - case SERIAL_BITS_6: port_bits = CS6; break; - case SERIAL_BITS_7: port_bits = CS7; break; - case SERIAL_BITS_8: port_bits = CS8; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (parity) { - case SERIAL_PARITY_NONE: port_parity = 0; break; - case SERIAL_PARITY_EVEN: port_parity = PARENB; break; - case SERIAL_PARITY_ODD: port_parity = PARENB | PARODD; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (stopbit) { - case SERIAL_STOPBIT_1: port_stop = 0; break; - case SERIAL_STOPBIT_2: port_stop = CSTOPB; break; - - default: - return PORT_ERR_UNKNOWN; - } - - /* reset the settings */ -#ifndef __sun /* Used by GNU and BSD. Ignore __SVR4 in test. */ - cfmakeraw(&h->newtio); -#else /* __sun */ - h->newtio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR - | IGNCR | ICRNL | IXON); - if (port_parity) - h->newtio.c_iflag |= INPCK; - - h->newtio.c_oflag &= ~OPOST; - h->newtio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - h->newtio.c_cflag &= ~(CSIZE | PARENB); - h->newtio.c_cflag |= CS8; -#endif /* __sun */ -#ifdef __QNXNTO__ - h->newtio.c_cflag &= ~(CSIZE | IHFLOW | OHFLOW); -#else - h->newtio.c_cflag &= ~(CSIZE | CRTSCTS); -#endif - h->newtio.c_cflag &= ~(CSIZE | CRTSCTS); - h->newtio.c_iflag &= ~(IXON | IXOFF | IXANY | IGNPAR); - h->newtio.c_lflag &= ~(ECHOK | ECHOCTL | ECHOKE); - h->newtio.c_oflag &= ~(OPOST | ONLCR); - - /* setup the new settings */ - cfsetispeed(&h->newtio, port_baud); - cfsetospeed(&h->newtio, port_baud); - h->newtio.c_cflag |= - port_parity | - port_bits | - port_stop | - CLOCAL | - CREAD; - - h->newtio.c_cc[VMIN] = 0; - h->newtio.c_cc[VTIME] = 5; /* in units of 0.1 s */ - - /* set the settings */ - serial_flush(h); - if (tcsetattr(h->fd, TCSANOW, &h->newtio) != 0) - return PORT_ERR_UNKNOWN; - -/* this check fails on CDC-ACM devices, bits 16 and 17 of cflag differ! - * it has been disabled below for now -jcw, 2015-11-09 - if (settings.c_cflag != h->newtio.c_cflag) - fprintf(stderr, "c_cflag mismatch %lx\n", - settings.c_cflag ^ h->newtio.c_cflag); - */ - - /* confirm they were set */ - tcgetattr(h->fd, &settings); - if (settings.c_iflag != h->newtio.c_iflag || - settings.c_oflag != h->newtio.c_oflag || - //settings.c_cflag != h->newtio.c_cflag || - settings.c_lflag != h->newtio.c_lflag) - return PORT_ERR_UNKNOWN; - - snprintf(h->setup_str, sizeof(h->setup_str), "%u %d%c%d", - serial_get_baud_int(baud), - serial_get_bits_int(bits), - serial_get_parity_str(parity), - serial_get_stopbit_int(stopbit)); - return PORT_ERR_OK; -} - -/* - * Roger clark. - * This function is no longer used. But has just been commented out in case it needs - * to be reinstated in the future - -static int startswith(const char *haystack, const char *needle) { - return strncmp(haystack, needle, strlen(needle)) == 0; -} -*/ - -static int is_tty(const char *path) { - char resolved[PATH_MAX]; - - if(!realpath(path, resolved)) return 0; - - - /* - * Roger Clark - * Commented out this check, because on OSX some devices are /dev/cu - * and some users use symbolic links to devices, hence the name may not even start - * with /dev - - if(startswith(resolved, "/dev/tty")) return 1; - - return 0; - */ - - return 1; -} - -static port_err_t serial_posix_open(struct port_interface *port, - struct port_options *ops) -{ - serial_t *h; - - /* 1. check device name match */ - if (!is_tty(ops->device)) - return PORT_ERR_NODEV; - - /* 2. check options */ - if (ops->baudRate == SERIAL_BAUD_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_parity(ops->serial_mode) == SERIAL_PARITY_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) - return PORT_ERR_UNKNOWN; - - /* 3. open it */ - h = serial_open(ops->device); - if (h == NULL) - return PORT_ERR_UNKNOWN; - - /* 4. set options */ - if (serial_setup(h, ops->baudRate, - serial_get_bits(ops->serial_mode), - serial_get_parity(ops->serial_mode), - serial_get_stopbit(ops->serial_mode) - ) != PORT_ERR_OK) { - serial_close(h); - return PORT_ERR_UNKNOWN; - } - - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t serial_posix_close(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - serial_close(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t serial_posix_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - ssize_t r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - r = read(h->fd, pos, nbyte); - if (r == 0) - return PORT_ERR_TIMEDOUT; - if (r < 0) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_posix_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - ssize_t r; - const uint8_t *pos = (const uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - r = write(h->fd, pos, nbyte); - if (r < 1) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_posix_gpio(struct port_interface *port, - serial_gpio_t n, int level) -{ - serial_t *h; - int bit, lines; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - switch (n) { - case GPIO_RTS: - bit = TIOCM_RTS; - break; - - case GPIO_DTR: - bit = TIOCM_DTR; - break; - - case GPIO_BRK: - if (level == 0) - return PORT_ERR_OK; - if (tcsendbreak(h->fd, 1)) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; - - default: - return PORT_ERR_UNKNOWN; - } - - /* handle RTS/DTR */ - if (ioctl(h->fd, TIOCMGET, &lines)) - return PORT_ERR_UNKNOWN; - lines = level ? lines | bit : lines & ~bit; - if (ioctl(h->fd, TIOCMSET, &lines)) - return PORT_ERR_UNKNOWN; - - return PORT_ERR_OK; -} - -static const char *serial_posix_get_cfg_str(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - return h ? h->setup_str : "INVALID"; -} - -struct port_interface port_serial = { - .name = "serial_posix", - .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, - .open = serial_posix_open, - .close = serial_posix_close, - .read = serial_posix_read, - .write = serial_posix_write, - .gpio = serial_posix_gpio, - .get_cfg_str = serial_posix_get_cfg_str, -}; diff --git a/macosx/src/stm32flash_serial/src/serial_w32.c b/macosx/src/stm32flash_serial/src/serial_w32.c deleted file mode 100644 index 56772c0a0..000000000 --- a/macosx/src/stm32flash_serial/src/serial_w32.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2010 Gareth McMullin - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - -struct serial { - HANDLE fd; - DCB oldtio; - DCB newtio; - char setup_str[11]; -}; - -static serial_t *serial_open(const char *device) -{ - serial_t *h = calloc(sizeof(serial_t), 1); - char *devName; - - /* timeout in ms */ - COMMTIMEOUTS timeouts = {MAXDWORD, MAXDWORD, 500, 0, 0}; - - /* Fix the device name if required */ - if (strlen(device) > 4 && device[0] != '\\') { - devName = calloc(1, strlen(device) + 5); - sprintf(devName, "\\\\.\\%s", device); - } else { - devName = (char *)device; - } - - /* Create file handle for port */ - h->fd = CreateFile(devName, GENERIC_READ | GENERIC_WRITE, - 0, /* Exclusive access */ - NULL, /* No security */ - OPEN_EXISTING, - 0, /* No overlap */ - NULL); - - if (devName != device) - free(devName); - - if (h->fd == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_FILE_NOT_FOUND) - fprintf(stderr, "File not found: %s\n", device); - return NULL; - } - - SetupComm(h->fd, 4096, 4096); /* Set input and output buffer size */ - - SetCommTimeouts(h->fd, &timeouts); - - SetCommMask(h->fd, EV_ERR); /* Notify us of error events */ - - GetCommState(h->fd, &h->oldtio); /* Retrieve port parameters */ - GetCommState(h->fd, &h->newtio); /* Retrieve port parameters */ - - /* PurgeComm(h->fd, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); */ - - return h; -} - -static void serial_flush(const serial_t *h) -{ - /* We shouldn't need to flush in non-overlapping (blocking) mode */ - /* tcflush(h->fd, TCIFLUSH); */ -} - -static void serial_close(serial_t *h) -{ - serial_flush(h); - SetCommState(h->fd, &h->oldtio); - CloseHandle(h->fd); - free(h); -} - -static port_err_t serial_setup(serial_t *h, - const serial_baud_t baud, - const serial_bits_t bits, - const serial_parity_t parity, - const serial_stopbit_t stopbit) -{ - switch (baud) { - case SERIAL_BAUD_1200: h->newtio.BaudRate = CBR_1200; break; - /* case SERIAL_BAUD_1800: h->newtio.BaudRate = CBR_1800; break; */ - case SERIAL_BAUD_2400: h->newtio.BaudRate = CBR_2400; break; - case SERIAL_BAUD_4800: h->newtio.BaudRate = CBR_4800; break; - case SERIAL_BAUD_9600: h->newtio.BaudRate = CBR_9600; break; - case SERIAL_BAUD_19200: h->newtio.BaudRate = CBR_19200; break; - case SERIAL_BAUD_38400: h->newtio.BaudRate = CBR_38400; break; - case SERIAL_BAUD_57600: h->newtio.BaudRate = CBR_57600; break; - case SERIAL_BAUD_115200: h->newtio.BaudRate = CBR_115200; break; - case SERIAL_BAUD_128000: h->newtio.BaudRate = CBR_128000; break; - case SERIAL_BAUD_256000: h->newtio.BaudRate = CBR_256000; break; - /* These are not defined in WinBase.h and might work or not */ - case SERIAL_BAUD_230400: h->newtio.BaudRate = 230400; break; - case SERIAL_BAUD_460800: h->newtio.BaudRate = 460800; break; - case SERIAL_BAUD_500000: h->newtio.BaudRate = 500000; break; - case SERIAL_BAUD_576000: h->newtio.BaudRate = 576000; break; - case SERIAL_BAUD_921600: h->newtio.BaudRate = 921600; break; - case SERIAL_BAUD_1000000: h->newtio.BaudRate = 1000000; break; - case SERIAL_BAUD_1500000: h->newtio.BaudRate = 1500000; break; - case SERIAL_BAUD_2000000: h->newtio.BaudRate = 2000000; break; - case SERIAL_BAUD_INVALID: - - default: - return PORT_ERR_UNKNOWN; - } - - switch (bits) { - case SERIAL_BITS_5: h->newtio.ByteSize = 5; break; - case SERIAL_BITS_6: h->newtio.ByteSize = 6; break; - case SERIAL_BITS_7: h->newtio.ByteSize = 7; break; - case SERIAL_BITS_8: h->newtio.ByteSize = 8; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (parity) { - case SERIAL_PARITY_NONE: h->newtio.Parity = NOPARITY; break; - case SERIAL_PARITY_EVEN: h->newtio.Parity = EVENPARITY; break; - case SERIAL_PARITY_ODD: h->newtio.Parity = ODDPARITY; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (stopbit) { - case SERIAL_STOPBIT_1: h->newtio.StopBits = ONESTOPBIT; break; - case SERIAL_STOPBIT_2: h->newtio.StopBits = TWOSTOPBITS; break; - - default: - return PORT_ERR_UNKNOWN; - } - - /* reset the settings */ - h->newtio.fOutxCtsFlow = FALSE; - h->newtio.fOutxDsrFlow = FALSE; - h->newtio.fOutX = FALSE; - h->newtio.fInX = FALSE; - h->newtio.fNull = 0; - h->newtio.fAbortOnError = 0; - - /* set the settings */ - serial_flush(h); - if (!SetCommState(h->fd, &h->newtio)) - return PORT_ERR_UNKNOWN; - - snprintf(h->setup_str, sizeof(h->setup_str), "%u %d%c%d", - serial_get_baud_int(baud), - serial_get_bits_int(bits), - serial_get_parity_str(parity), - serial_get_stopbit_int(stopbit) - ); - return PORT_ERR_OK; -} - -static port_err_t serial_w32_open(struct port_interface *port, - struct port_options *ops) -{ - serial_t *h; - - /* 1. check device name match */ - if (!((strlen(ops->device) == 4 || strlen(ops->device) == 5) - && !strncmp(ops->device, "COM", 3) && isdigit(ops->device[3])) - && !(!strncmp(ops->device, "\\\\.\\COM", strlen("\\\\.\\COM")) - && isdigit(ops->device[strlen("\\\\.\\COM")]))) - return PORT_ERR_NODEV; - - /* 2. check options */ - if (ops->baudRate == SERIAL_BAUD_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_parity(ops->serial_mode) == SERIAL_PARITY_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) - return PORT_ERR_UNKNOWN; - - /* 3. open it */ - h = serial_open(ops->device); - if (h == NULL) - return PORT_ERR_UNKNOWN; - - /* 4. set options */ - if (serial_setup(h, ops->baudRate, - serial_get_bits(ops->serial_mode), - serial_get_parity(ops->serial_mode), - serial_get_stopbit(ops->serial_mode) - ) != PORT_ERR_OK) { - serial_close(h); - return PORT_ERR_UNKNOWN; - } - - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t serial_w32_close(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - serial_close(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t serial_w32_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - DWORD r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - ReadFile(h->fd, pos, nbyte, &r, NULL); - if (r == 0) - return PORT_ERR_TIMEDOUT; - if (r < 0) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_w32_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - DWORD r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - if (!WriteFile(h->fd, pos, nbyte, &r, NULL)) - return PORT_ERR_UNKNOWN; - if (r < 1) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_w32_gpio(struct port_interface *port, - serial_gpio_t n, int level) -{ - serial_t *h; - int bit; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - switch (n) { - case GPIO_RTS: - bit = level ? SETRTS : CLRRTS; - break; - - case GPIO_DTR: - bit = level ? SETDTR : CLRDTR; - break; - - case GPIO_BRK: - if (level == 0) - return PORT_ERR_OK; - if (EscapeCommFunction(h->fd, SETBREAK) == 0) - return PORT_ERR_UNKNOWN; - usleep(500000); - if (EscapeCommFunction(h->fd, CLRBREAK) == 0) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; - - default: - return PORT_ERR_UNKNOWN; - } - - /* handle RTS/DTR */ - if (EscapeCommFunction(h->fd, bit) == 0) - return PORT_ERR_UNKNOWN; - - return PORT_ERR_OK; -} - -static const char *serial_w32_get_cfg_str(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - return h ? h->setup_str : "INVALID"; -} - -struct port_interface port_serial = { - .name = "serial_w32", - .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, - .open = serial_w32_open, - .close = serial_w32_close, - .read = serial_w32_read, - .write = serial_w32_write, - .gpio = serial_w32_gpio, - .get_cfg_str = serial_w32_get_cfg_str, -}; diff --git a/macosx/src/stm32flash_serial/src/stm32.c b/macosx/src/stm32flash_serial/src/stm32.c deleted file mode 100644 index 74047d244..000000000 --- a/macosx/src/stm32flash_serial/src/stm32.c +++ /dev/null @@ -1,1048 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright 2010 Geoffrey McRae - Copyright 2012-2014 Tormod Volden - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include - -#include "stm32.h" -#include "port.h" -#include "utils.h" - -#define STM32_ACK 0x79 -#define STM32_NACK 0x1F -#define STM32_BUSY 0x76 - -#define STM32_CMD_INIT 0x7F -#define STM32_CMD_GET 0x00 /* get the version and command supported */ -#define STM32_CMD_GVR 0x01 /* get version and read protection status */ -#define STM32_CMD_GID 0x02 /* get ID */ -#define STM32_CMD_RM 0x11 /* read memory */ -#define STM32_CMD_GO 0x21 /* go */ -#define STM32_CMD_WM 0x31 /* write memory */ -#define STM32_CMD_WM_NS 0x32 /* no-stretch write memory */ -#define STM32_CMD_ER 0x43 /* erase */ -#define STM32_CMD_EE 0x44 /* extended erase */ -#define STM32_CMD_EE_NS 0x45 /* extended erase no-stretch */ -#define STM32_CMD_WP 0x63 /* write protect */ -#define STM32_CMD_WP_NS 0x64 /* write protect no-stretch */ -#define STM32_CMD_UW 0x73 /* write unprotect */ -#define STM32_CMD_UW_NS 0x74 /* write unprotect no-stretch */ -#define STM32_CMD_RP 0x82 /* readout protect */ -#define STM32_CMD_RP_NS 0x83 /* readout protect no-stretch */ -#define STM32_CMD_UR 0x92 /* readout unprotect */ -#define STM32_CMD_UR_NS 0x93 /* readout unprotect no-stretch */ -#define STM32_CMD_CRC 0xA1 /* compute CRC */ -#define STM32_CMD_ERR 0xFF /* not a valid command */ - -#define STM32_RESYNC_TIMEOUT 35 /* seconds */ -#define STM32_MASSERASE_TIMEOUT 35 /* seconds */ -#define STM32_SECTERASE_TIMEOUT 5 /* seconds */ -#define STM32_BLKWRITE_TIMEOUT 1 /* seconds */ -#define STM32_WUNPROT_TIMEOUT 1 /* seconds */ -#define STM32_WPROT_TIMEOUT 1 /* seconds */ -#define STM32_RPROT_TIMEOUT 1 /* seconds */ - -#define STM32_CMD_GET_LENGTH 17 /* bytes in the reply */ - -struct stm32_cmd { - uint8_t get; - uint8_t gvr; - uint8_t gid; - uint8_t rm; - uint8_t go; - uint8_t wm; - uint8_t er; /* this may be extended erase */ - uint8_t wp; - uint8_t uw; - uint8_t rp; - uint8_t ur; - uint8_t crc; -}; - -/* Reset code for ARMv7-M (Cortex-M3) and ARMv6-M (Cortex-M0) - * see ARMv7-M or ARMv6-M Architecture Reference Manual (table B3-8) - * or "The definitive guide to the ARM Cortex-M3", section 14.4. - */ -static const uint8_t stm_reset_code[] = { - 0x01, 0x49, // ldr r1, [pc, #4] ; () - 0x02, 0x4A, // ldr r2, [pc, #8] ; () - 0x0A, 0x60, // str r2, [r1, #0] - 0xfe, 0xe7, // endless: b endless - 0x0c, 0xed, 0x00, 0xe0, // .word 0xe000ed0c = NVIC AIRCR register address - 0x04, 0x00, 0xfa, 0x05 // .word 0x05fa0004 = VECTKEY | SYSRESETREQ -}; - -static const uint32_t stm_reset_code_length = sizeof(stm_reset_code); - -extern const stm32_dev_t devices[]; - -static void stm32_warn_stretching(const char *f) -{ - fprintf(stderr, "Attention !!!\n"); - fprintf(stderr, "\tThis %s error could be caused by your I2C\n", f); - fprintf(stderr, "\tcontroller not accepting \"clock stretching\"\n"); - fprintf(stderr, "\tas required by bootloader.\n"); - fprintf(stderr, "\tCheck \"I2C.txt\" in stm32flash source code.\n"); -} - -static stm32_err_t stm32_get_ack_timeout(const stm32_t *stm, time_t timeout) -{ - struct port_interface *port = stm->port; - uint8_t byte; - port_err_t p_err; - time_t t0, t1; - - if (!(port->flags & PORT_RETRY)) - timeout = 0; - - if (timeout) - time(&t0); - - do { - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_TIMEDOUT && timeout) { - time(&t1); - if (t1 < t0 + timeout) - continue; - } - - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to read ACK byte\n"); - return STM32_ERR_UNKNOWN; - } - - if (byte == STM32_ACK) - return STM32_ERR_OK; - if (byte == STM32_NACK) - return STM32_ERR_NACK; - if (byte != STM32_BUSY) { - fprintf(stderr, "Got byte 0x%02x instead of ACK\n", - byte); - return STM32_ERR_UNKNOWN; - } - } while (1); -} - -static stm32_err_t stm32_get_ack(const stm32_t *stm) -{ - return stm32_get_ack_timeout(stm, 0); -} - -static stm32_err_t stm32_send_command_timeout(const stm32_t *stm, - const uint8_t cmd, - time_t timeout) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - port_err_t p_err; - uint8_t buf[2]; - - buf[0] = cmd; - buf[1] = cmd ^ 0xFF; - p_err = port->write(port, buf, 2); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send command\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, timeout); - if (s_err == STM32_ERR_OK) - return STM32_ERR_OK; - if (s_err == STM32_ERR_NACK) - fprintf(stderr, "Got NACK from device on command 0x%02x\n", cmd); - else - fprintf(stderr, "Unexpected reply from device on command 0x%02x\n", cmd); - return STM32_ERR_UNKNOWN; -} - -static stm32_err_t stm32_send_command(const stm32_t *stm, const uint8_t cmd) -{ - return stm32_send_command_timeout(stm, cmd, 0); -} - -/* if we have lost sync, send a wrong command and expect a NACK */ -static stm32_err_t stm32_resync(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - uint8_t buf[2], ack; - time_t t0, t1; - - time(&t0); - t1 = t0; - - buf[0] = STM32_CMD_ERR; - buf[1] = STM32_CMD_ERR ^ 0xFF; - while (t1 < t0 + STM32_RESYNC_TIMEOUT) { - p_err = port->write(port, buf, 2); - if (p_err != PORT_ERR_OK) { - usleep(500000); - time(&t1); - continue; - } - p_err = port->read(port, &ack, 1); - if (p_err != PORT_ERR_OK) { - time(&t1); - continue; - } - if (ack == STM32_NACK) - return STM32_ERR_OK; - time(&t1); - } - return STM32_ERR_UNKNOWN; -} - -/* - * some command receive reply frame with variable length, and length is - * embedded in reply frame itself. - * We can guess the length, but if we guess wrong the protocol gets out - * of sync. - * Use resync for frame oriented interfaces (e.g. I2C) and byte-by-byte - * read for byte oriented interfaces (e.g. UART). - * - * to run safely, data buffer should be allocated for 256+1 bytes - * - * len is value of the first byte in the frame. - */ -static stm32_err_t stm32_guess_len_cmd(const stm32_t *stm, uint8_t cmd, - uint8_t *data, unsigned int len) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - if (port->flags & PORT_BYTE) { - /* interface is UART-like */ - p_err = port->read(port, data, 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - len = data[0]; - p_err = port->read(port, data + 1, len + 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; - } - - p_err = port->read(port, data, len + 2); - if (p_err == PORT_ERR_OK && len == data[0]) - return STM32_ERR_OK; - if (p_err != PORT_ERR_OK) { - /* restart with only one byte */ - if (stm32_resync(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - p_err = port->read(port, data, 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - } - - fprintf(stderr, "Re sync (len = %d)\n", data[0]); - if (stm32_resync(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - len = data[0]; - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - p_err = port->read(port, data, len + 2); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; -} - -/* - * Some interface, e.g. UART, requires a specific init sequence to let STM32 - * autodetect the interface speed. - * The sequence is only required one time after reset. - * stm32flash has command line flag "-c" to prevent sending the init sequence - * in case it was already sent before. - * User can easily forget adding "-c". In this case the bootloader would - * interpret the init sequence as part of a command message, then waiting for - * the rest of the message blocking the interface. - * This function sends the init sequence and, in case of timeout, recovers - * the interface. - */ -static stm32_err_t stm32_send_init_seq(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - uint8_t byte, cmd = STM32_CMD_INIT; - - p_err = port->write(port, &cmd, 1); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send init to device\n"); - return STM32_ERR_UNKNOWN; - } - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_OK && byte == STM32_ACK) - return STM32_ERR_OK; - if (p_err == PORT_ERR_OK && byte == STM32_NACK) { - /* We could get error later, but let's continue, for now. */ - fprintf(stderr, - "Warning: the interface was not closed properly.\n"); - return STM32_ERR_OK; - } - if (p_err != PORT_ERR_TIMEDOUT) { - fprintf(stderr, "Failed to init device.\n"); - return STM32_ERR_UNKNOWN; - } - - /* - * Check if previous STM32_CMD_INIT was taken as first byte - * of a command. Send a new byte, we should get back a NACK. - */ - p_err = port->write(port, &cmd, 1); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send init to device\n"); - return STM32_ERR_UNKNOWN; - } - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_OK && byte == STM32_NACK) - return STM32_ERR_OK; - fprintf(stderr, "Failed to init device.\n"); - return STM32_ERR_UNKNOWN; -} - -/* find newer command by higher code */ -#define newer(prev, a) (((prev) == STM32_CMD_ERR) \ - ? (a) \ - : (((prev) > (a)) ? (prev) : (a))) - -stm32_t *stm32_init(struct port_interface *port, const char init) -{ - uint8_t len, val, buf[257]; - stm32_t *stm; - int i, new_cmds; - - stm = calloc(sizeof(stm32_t), 1); - stm->cmd = malloc(sizeof(stm32_cmd_t)); - memset(stm->cmd, STM32_CMD_ERR, sizeof(stm32_cmd_t)); - stm->port = port; - - if ((port->flags & PORT_CMD_INIT) && init) - if (stm32_send_init_seq(stm) != STM32_ERR_OK) - return NULL; - - /* get the version and read protection status */ - if (stm32_send_command(stm, STM32_CMD_GVR) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - /* From AN, only UART bootloader returns 3 bytes */ - len = (port->flags & PORT_GVR_ETX) ? 3 : 1; - if (port->read(port, buf, len) != PORT_ERR_OK) - return NULL; - stm->version = buf[0]; - stm->option1 = (port->flags & PORT_GVR_ETX) ? buf[1] : 0; - stm->option2 = (port->flags & PORT_GVR_ETX) ? buf[2] : 0; - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - /* get the bootloader information */ - len = STM32_CMD_GET_LENGTH; - if (port->cmd_get_reply) - for (i = 0; port->cmd_get_reply[i].length; i++) - if (stm->version == port->cmd_get_reply[i].version) { - len = port->cmd_get_reply[i].length; - break; - } - if (stm32_guess_len_cmd(stm, STM32_CMD_GET, buf, len) != STM32_ERR_OK) - return NULL; - len = buf[0] + 1; - stm->bl_version = buf[1]; - new_cmds = 0; - for (i = 1; i < len; i++) { - val = buf[i + 1]; - switch (val) { - case STM32_CMD_GET: - stm->cmd->get = val; break; - case STM32_CMD_GVR: - stm->cmd->gvr = val; break; - case STM32_CMD_GID: - stm->cmd->gid = val; break; - case STM32_CMD_RM: - stm->cmd->rm = val; break; - case STM32_CMD_GO: - stm->cmd->go = val; break; - case STM32_CMD_WM: - case STM32_CMD_WM_NS: - stm->cmd->wm = newer(stm->cmd->wm, val); - break; - case STM32_CMD_ER: - case STM32_CMD_EE: - case STM32_CMD_EE_NS: - stm->cmd->er = newer(stm->cmd->er, val); - break; - case STM32_CMD_WP: - case STM32_CMD_WP_NS: - stm->cmd->wp = newer(stm->cmd->wp, val); - break; - case STM32_CMD_UW: - case STM32_CMD_UW_NS: - stm->cmd->uw = newer(stm->cmd->uw, val); - break; - case STM32_CMD_RP: - case STM32_CMD_RP_NS: - stm->cmd->rp = newer(stm->cmd->rp, val); - break; - case STM32_CMD_UR: - case STM32_CMD_UR_NS: - stm->cmd->ur = newer(stm->cmd->ur, val); - break; - case STM32_CMD_CRC: - stm->cmd->crc = newer(stm->cmd->crc, val); - break; - default: - if (new_cmds++ == 0) - fprintf(stderr, - "GET returns unknown commands (0x%2x", - val); - else - fprintf(stderr, ", 0x%2x", val); - } - } - if (new_cmds) - fprintf(stderr, ")\n"); - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - if (stm->cmd->get == STM32_CMD_ERR - || stm->cmd->gvr == STM32_CMD_ERR - || stm->cmd->gid == STM32_CMD_ERR) { - fprintf(stderr, "Error: bootloader did not returned correct information from GET command\n"); - return NULL; - } - - /* get the device ID */ - if (stm32_guess_len_cmd(stm, stm->cmd->gid, buf, 1) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - len = buf[0] + 1; - if (len < 2) { - stm32_close(stm); - fprintf(stderr, "Only %d bytes sent in the PID, unknown/unsupported device\n", len); - return NULL; - } - stm->pid = (buf[1] << 8) | buf[2]; - if (len > 2) { - fprintf(stderr, "This bootloader returns %d extra bytes in PID:", len); - for (i = 2; i <= len ; i++) - fprintf(stderr, " %02x", buf[i]); - fprintf(stderr, "\n"); - } - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - stm->dev = devices; - while (stm->dev->id != 0x00 && stm->dev->id != stm->pid) - ++stm->dev; - - if (!stm->dev->id) { - fprintf(stderr, "Unknown/unsupported device (Device ID: 0x%03x)\n", stm->pid); - stm32_close(stm); - return NULL; - } - - return stm; -} - -void stm32_close(stm32_t *stm) -{ - if (stm) - free(stm->cmd); - free(stm); -} - -stm32_err_t stm32_read_memory(const stm32_t *stm, uint32_t address, - uint8_t data[], unsigned int len) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (!len) - return STM32_ERR_OK; - - if (len > 256) { - fprintf(stderr, "Error: READ length limit at 256 bytes\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->rm == STM32_CMD_ERR) { - fprintf(stderr, "Error: READ command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->rm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_send_command(stm, len - 1) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (port->read(port, data, len) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - return STM32_ERR_OK; -} - -stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, - const uint8_t data[], unsigned int len) -{ - struct port_interface *port = stm->port; - uint8_t cs, buf[256 + 2]; - unsigned int i, aligned_len; - stm32_err_t s_err; - - if (!len) - return STM32_ERR_OK; - - if (len > 256) { - fprintf(stderr, "Error: READ length limit at 256 bytes\n"); - return STM32_ERR_UNKNOWN; - } - - /* must be 32bit aligned */ - if (address & 0x3 || len & 0x3) { - fprintf(stderr, "Error: WRITE address and length must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->wm == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - /* send the address and checksum */ - if (stm32_send_command(stm, stm->cmd->wm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - aligned_len = (len + 3) & ~3; - cs = aligned_len - 1; - buf[0] = aligned_len - 1; - for (i = 0; i < len; i++) { - cs ^= data[i]; - buf[i + 1] = data[i]; - } - /* padding data */ - for (i = len; i < aligned_len; i++) { - cs ^= 0xFF; - buf[i + 1] = 0xFF; - } - buf[aligned_len + 1] = cs; - if (port->write(port, buf, aligned_len + 2) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_BLKWRITE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->wm != STM32_CMD_WM_NS) - stm32_warn_stretching("write"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_wunprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->uw == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE UNPROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->uw) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_WUNPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to WRITE UNPROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->uw != STM32_CMD_UW_NS) - stm32_warn_stretching("WRITE UNPROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_wprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->wp == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE PROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->wp) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_WPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to WRITE PROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->wp != STM32_CMD_WP_NS) - stm32_warn_stretching("WRITE PROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_runprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->ur == STM32_CMD_ERR) { - fprintf(stderr, "Error: READOUT UNPROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->ur) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to READOUT UNPROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->ur != STM32_CMD_UR_NS) - stm32_warn_stretching("READOUT UNPROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_readprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->rp == STM32_CMD_ERR) { - fprintf(stderr, "Error: READOUT PROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->rp) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_RPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to READOUT PROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->rp != STM32_CMD_RP_NS) - stm32_warn_stretching("READOUT PROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - port_err_t p_err; - - if (!pages) - return STM32_ERR_OK; - - if (stm->cmd->er == STM32_CMD_ERR) { - fprintf(stderr, "Error: ERASE command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->er) != STM32_ERR_OK) { - fprintf(stderr, "Can't initiate chip erase!\n"); - return STM32_ERR_UNKNOWN; - } - - /* The erase command reported by the bootloader is either 0x43, 0x44 or 0x45 */ - /* 0x44 is Extended Erase, a 2 byte based protocol and needs to be handled differently. */ - /* 0x45 is clock no-stretching version of Extended Erase for I2C port. */ - if (stm->cmd->er != STM32_CMD_ER) { - /* Not all chips using Extended Erase support mass erase */ - /* Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range */ - /* So if someone has not overridden the default, but uses one of these chips, take it out of */ - /* mass erase mode, so it will be done page by page. This maximum might not be correct either! */ - if (stm->pid == 0x416 && pages == 0xFF) - pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ - - if (pages == 0xFF) { - uint8_t buf[3]; - - /* 0xFFFF the magic number for mass erase */ - buf[0] = 0xFF; - buf[1] = 0xFF; - buf[2] = 0x00; /* checksum */ - if (port->write(port, buf, 3) != PORT_ERR_OK) { - fprintf(stderr, "Mass erase error.\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Mass erase failed. Try specifying the number of pages to be erased.\n"); - if (port->flags & PORT_STRETCH_W - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } - - uint16_t pg_num; - uint8_t pg_byte; - uint8_t cs = 0; - uint8_t *buf; - int i = 0; - - buf = malloc(2 + 2 * pages + 1); - if (!buf) - return STM32_ERR_UNKNOWN; - - /* Number of pages to be erased - 1, two bytes, MSB first */ - pg_byte = (pages - 1) >> 8; - buf[i++] = pg_byte; - cs ^= pg_byte; - pg_byte = (pages - 1) & 0xFF; - buf[i++] = pg_byte; - cs ^= pg_byte; - - for (pg_num = spage; pg_num < spage + pages; pg_num++) { - pg_byte = pg_num >> 8; - cs ^= pg_byte; - buf[i++] = pg_byte; - pg_byte = pg_num & 0xFF; - cs ^= pg_byte; - buf[i++] = pg_byte; - } - buf[i++] = cs; - p_err = port->write(port, buf, i); - free(buf); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Page-by-page erase error.\n"); - return STM32_ERR_UNKNOWN; - } - - s_err = stm32_get_ack_timeout(stm, pages * STM32_SECTERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Page-by-page erase failed. Check the maximum pages your device supports.\n"); - if (port->flags & PORT_STRETCH_W - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - - return STM32_ERR_OK; - } - - /* And now the regular erase (0x43) for all other chips */ - if (pages == 0xFF) { - s_err = stm32_send_command_timeout(stm, 0xFF, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } else { - uint8_t cs = 0; - uint8_t pg_num; - uint8_t *buf; - int i = 0; - - buf = malloc(1 + pages + 1); - if (!buf) - return STM32_ERR_UNKNOWN; - - buf[i++] = pages - 1; - cs ^= (pages-1); - for (pg_num = spage; pg_num < (pages + spage); pg_num++) { - buf[i++] = pg_num; - cs ^= pg_num; - } - buf[i++] = cs; - p_err = port->write(port, buf, i); - free(buf); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Erase failed.\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } -} - -static stm32_err_t stm32_run_raw_code(const stm32_t *stm, - uint32_t target_address, - const uint8_t *code, uint32_t code_size) -{ - uint32_t stack_le = le_u32(0x20002000); - uint32_t code_address_le = le_u32(target_address + 8); - uint32_t length = code_size + 8; - uint8_t *mem, *pos; - uint32_t address, w; - - /* Must be 32-bit aligned */ - if (target_address & 0x3) { - fprintf(stderr, "Error: code address must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - mem = malloc(length); - if (!mem) - return STM32_ERR_UNKNOWN; - - memcpy(mem, &stack_le, sizeof(uint32_t)); - memcpy(mem + 4, &code_address_le, sizeof(uint32_t)); - memcpy(mem + 8, code, code_size); - - pos = mem; - address = target_address; - while (length > 0) { - w = length > 256 ? 256 : length; - if (stm32_write_memory(stm, address, pos, w) != STM32_ERR_OK) { - free(mem); - return STM32_ERR_UNKNOWN; - } - - address += w; - pos += w; - length -= w; - } - - free(mem); - return stm32_go(stm, target_address); -} - -stm32_err_t stm32_go(const stm32_t *stm, uint32_t address) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (stm->cmd->go == STM32_CMD_ERR) { - fprintf(stderr, "Error: GO command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->go) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; -} - -stm32_err_t stm32_reset_device(const stm32_t *stm) -{ - uint32_t target_address = stm->dev->ram_start; - - return stm32_run_raw_code(stm, target_address, stm_reset_code, stm_reset_code_length); -} - -stm32_err_t stm32_crc_memory(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (address & 0x3 || length & 0x3) { - fprintf(stderr, "Start and end addresses must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->crc == STM32_CMD_ERR) { - fprintf(stderr, "Error: CRC command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->crc) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = length >> 24; - buf[1] = (length >> 16) & 0xFF; - buf[2] = (length >> 8) & 0xFF; - buf[3] = length & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (port->read(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (buf[4] != (buf[0] ^ buf[1] ^ buf[2] ^ buf[3])) - return STM32_ERR_UNKNOWN; - - *crc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; - return STM32_ERR_OK; -} - -/* - * CRC computed by STM32 is similar to the standard crc32_be() - * implemented, for example, in Linux kernel in ./lib/crc32.c - * But STM32 computes it on units of 32 bits word and swaps the - * bytes of the word before the computation. - * Due to byte swap, I cannot use any CRC available in existing - * libraries, so here is a simple not optimized implementation. - */ -#define CRCPOLY_BE 0x04c11db7 -#define CRC_MSBMASK 0x80000000 -#define CRC_INIT_VALUE 0xFFFFFFFF -uint32_t stm32_sw_crc(uint32_t crc, uint8_t *buf, unsigned int len) -{ - int i; - uint32_t data; - - if (len & 0x3) { - fprintf(stderr, "Buffer length must be multiple of 4 bytes\n"); - return 0; - } - - while (len) { - data = *buf++; - data |= *buf++ << 8; - data |= *buf++ << 16; - data |= *buf++ << 24; - len -= 4; - - crc ^= data; - - for (i = 0; i < 32; i++) - if (crc & CRC_MSBMASK) - crc = (crc << 1) ^ CRCPOLY_BE; - else - crc = (crc << 1); - } - return crc; -} - -stm32_err_t stm32_crc_wrapper(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc) -{ - uint8_t buf[256]; - uint32_t start, total_len, len, current_crc; - - if (address & 0x3 || length & 0x3) { - fprintf(stderr, "Start and end addresses must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->crc != STM32_CMD_ERR) - return stm32_crc_memory(stm, address, length, crc); - - start = address; - total_len = length; - current_crc = CRC_INIT_VALUE; - while (length) { - len = length > 256 ? 256 : length; - if (stm32_read_memory(stm, address, buf, len) != STM32_ERR_OK) { - fprintf(stderr, - "Failed to read memory at address 0x%08x, target write-protected?\n", - address); - return STM32_ERR_UNKNOWN; - } - current_crc = stm32_sw_crc(current_crc, buf, len); - length -= len; - address += len; - - fprintf(stderr, - "\rCRC address 0x%08x (%.2f%%) ", - address, - (100.0f / (float)total_len) * (float)(address - start) - ); - fflush(stderr); - } - fprintf(stderr, "Done.\n"); - *crc = current_crc; - return STM32_ERR_OK; -} diff --git a/macosx/src/stm32flash_serial/src/stm32.h b/macosx/src/stm32flash_serial/src/stm32.h deleted file mode 100644 index 1688fcb4b..000000000 --- a/macosx/src/stm32flash_serial/src/stm32.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _STM32_H -#define _STM32_H - -#include -#include "serial.h" - -#define STM32_MAX_RX_FRAME 256 /* cmd read memory */ -#define STM32_MAX_TX_FRAME (1 + 256 + 1) /* cmd write memory */ - -typedef enum { - STM32_ERR_OK = 0, - STM32_ERR_UNKNOWN, /* Generic error */ - STM32_ERR_NACK, - STM32_ERR_NO_CMD, /* Command not available in bootloader */ -} stm32_err_t; - -typedef struct stm32 stm32_t; -typedef struct stm32_cmd stm32_cmd_t; -typedef struct stm32_dev stm32_dev_t; - -struct stm32 { - const serial_t *serial; - struct port_interface *port; - uint8_t bl_version; - uint8_t version; - uint8_t option1, option2; - uint16_t pid; - stm32_cmd_t *cmd; - const stm32_dev_t *dev; -}; - -struct stm32_dev { - uint16_t id; - const char *name; - uint32_t ram_start, ram_end; - uint32_t fl_start, fl_end; - uint16_t fl_pps; // pages per sector - uint16_t fl_ps; // page size - uint32_t opt_start, opt_end; - uint32_t mem_start, mem_end; -}; - -stm32_t *stm32_init(struct port_interface *port, const char init); -void stm32_close(stm32_t *stm); -stm32_err_t stm32_read_memory(const stm32_t *stm, uint32_t address, - uint8_t data[], unsigned int len); -stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, - const uint8_t data[], unsigned int len); -stm32_err_t stm32_wunprot_memory(const stm32_t *stm); -stm32_err_t stm32_wprot_memory(const stm32_t *stm); -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, - uint8_t pages); -stm32_err_t stm32_go(const stm32_t *stm, uint32_t address); -stm32_err_t stm32_reset_device(const stm32_t *stm); -stm32_err_t stm32_readprot_memory(const stm32_t *stm); -stm32_err_t stm32_runprot_memory(const stm32_t *stm); -stm32_err_t stm32_crc_memory(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc); -stm32_err_t stm32_crc_wrapper(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc); -uint32_t stm32_sw_crc(uint32_t crc, uint8_t *buf, unsigned int len); - -#endif - diff --git a/macosx/src/stm32flash_serial/src/stm32flash.1 b/macosx/src/stm32flash_serial/src/stm32flash.1 deleted file mode 100644 index d37292f6a..000000000 --- a/macosx/src/stm32flash_serial/src/stm32flash.1 +++ /dev/null @@ -1,407 +0,0 @@ -.TH STM32FLASH 1 "2013\-11\-03" STM32FLASH "User command" -.SH NAME -stm32flash \- flashing utility for STM32 and STM32W through UART or I2C -.SH SYNOPSIS -.B stm32flash -.RB [ \-cfhjkouvCR ] -.RB [ \-a -.IR bus_address ] -.RB [ \-b -.IR baud_rate ] -.RB [ \-m -.IR serial_mode ] -.RB [ \-r -.IR filename ] -.RB [ \-w -.IR filename ] -.RB [ \-e -.IR num ] -.RB [ \-n -.IR count ] -.RB [ \-g -.IR address ] -.RB [ \-s -.IR start_page ] -.RB [ \-S -.IR address [: length ]] -.RB [ \-F -.IR RX_length [: TX_length ]] -.RB [ \-i -.IR GPIO_string ] -.RI [ tty_device -.R | -.IR i2c_device ] - -.SH DESCRIPTION -.B stm32flash -reads or writes the flash memory of STM32 and STM32W. - -It requires the STM32[W] to embed a bootloader compliant with ST -application note AN3155. -.B stm32flash -uses the serial port -.I tty_device -to interact with the bootloader of STM32[W]. - -.SH OPTIONS -.TP -.BI "\-a" " bus_address" -Specify address on bus for -.IR i2c_device . -This option is mandatory for I2C interface. - -.TP -.BI "\-b" " baud_rate" -Specify baud rate speed of -.IR tty_device . -Please notice that the ST bootloader can automatically detect the baud rate, -as explaned in chapter 2 of AN3155. -This option could be required together with option -.B "\-c" -or if following interaction with bootloader is expected. -Default is -.IR 57600 . - -.TP -.BI "\-m" " mode" -Specify the format of UART data. -.I mode -is a three characters long string where each character specifies, in -this strict order, character size, parity and stop bits. -The only values currenly used are -.I 8e1 -for standard STM32 bootloader and -.I 8n1 -for standard STM32W bootloader. -Default is -.IR 8e1 . - -.TP -.BI "\-r" " filename" -Specify to read the STM32[W] flash and write its content in -.I filename -in raw binary format (see below -.BR "FORMAT CONVERSION" ). - -.TP -.BI "\-w" " filename" -Specify to write the STM32[W] flash with the content of -.IR filename . -File format can be either raw binary or intel hex (see below -.BR "FORMAT CONVERSION" ). -The file format is automatically detected. -To by\-pass format detection and force binary mode (e.g. to -write an intel hex content in STM32[W] flash), use -.B \-f -option. - -.TP -.B \-u -Specify to disable write\-protection from STM32[W] flash. -The STM32[W] will be reset after this operation. - -.TP -.B \-j -Enable the flash read\-protection. - -.TP -.B \-k -Disable the flash read\-protection. - -.TP -.B \-o -Erase only. - -.TP -.BI "\-e" " num" -Specify to erase only -.I num -pages before writing the flash. Default is to erase the whole flash. With -.B \-e 0 -the flash would not be erased. - -.TP -.B \-v -Specify to verify flash content after write operation. - -.TP -.BI "\-n" " count" -Specify to retry failed writes up to -.I count -times. Default is 10 times. - -.TP -.BI "\-g" " address" -Specify address to start execution from (0 = flash start). - -.TP -.BI "\-s" " start_page" -Specify flash page offset (0 = flash start). - -.TP -.BI "\-S" " address" "[:" "length" "]" -Specify start address and optionally length for read/write/erase/crc operations. - -.TP -.BI "\-F" " RX_length" "[:" "TX_length" "]" -Specify the maximum frame size for the current interface. -Due to STM32 bootloader protocol, host will never handle frames bigger than -256 byte in RX or 258 byte in TX. -Due to current code, lowest limit in RX is 20 byte (to read a complete reply -of command GET). Minimum limit in TX is 5 byte, required by protocol. - -.TP -.B \-f -Force binary parser while reading file with -.BR "\-w" "." - -.TP -.B \-h -Show help. - -.TP -.B \-c -Specify to resume the existing UART connection and don't send initial -INIT sequence to detect baud rate. Baud rate must be kept the same as the -existing connection. This is useful if the reset fails. - -.TP -.BI "\-i" " GPIO_string" -Specify the GPIO sequences on the host to force STM32[W] to enter and -exit bootloader mode. GPIO can either be real GPIO connected from host to -STM32[W] beside the UART connection, or UART's modem signals used as -GPIO. (See below -.B BOOTLOADER GPIO SEQUENCE -for the format of -.I GPIO_string -and further explanation). - -.TP -.B \-C -Specify to compute CRC on memory content. -By default the CRC is computed on the whole flash content. -Use -.B "\-S" -to provide different memory address range. - -.TP -.B \-R -Specify to reset the device at exit. -This option is ignored if either -.BR "\-g" "," -.BR "\-j" "," -.B "\-k" -or -.B "\-u" -is also specified. - -.SH BOOTLOADER GPIO SEQUENCE -This feature is currently available on Linux host only. - -As explained in ST application note AN2606, after reset the STM32 will -execute either the application program in user flash or the bootloader, -depending on the level applied at specific pins of STM32 during reset. - -STM32 bootloader is automatically activated by configuring the pins -BOOT0="high" and BOOT1="low" and then by applying a reset. -Application program in user flash is activated by configuring the pin -BOOT0="low" (the level on BOOT1 is ignored) and then by applying a reset. - -When GPIO from host computer are connected to either configuration and -reset pins of STM32, -.B stm32flash -can control the host GPIO to reset STM32 and to force execution of -bootloader or execution of application program. - -The sequence of GPIO values to entry to and exit from bootloader mode is -provided with command line option -.B "\-i" -.IR "GPIO_string" . - -.PD 0 -The format of -.IR "GPIO_string" " is:" -.RS -GPIO_string = [entry sequence][:[exit sequence]] -.P -sequence = [\-]n[,sequence] -.RE -.P -In the above sequences, negative numbers correspond to GPIO at "low" level; -numbers without sign correspond to GPIO at "high" level. -The value "n" can either be the GPIO number on the host system or the -string "rts", "dtr" or "brk". The strings "rts" and "dtr" drive the -corresponding UART's modem lines RTS and DTR as GPIO. -The string "brk" forces the UART to send a BREAK sequence on TX line; -after BREAK the UART is returned in normal "non\-break" mode. -Note: the string "\-brk" has no effect and is ignored. -.PD - -.PD 0 -As example, let's suppose the following connection between host and STM32: -.IP \(bu 2 -host GPIO_3 connected to reset pin of STM32; -.IP \(bu 2 -host GPIO_4 connected to STM32 pin BOOT0; -.IP \(bu 2 -host GPIO_5 connected to STM32 pin BOOT1. -.PD -.P - -In this case, the sequence to enter in bootloader mode is: first put -GPIO_4="high" and GPIO_5="low"; then send reset pulse by GPIO_3="low" -followed by GPIO_3="high". -The corresponding string for -.I GPIO_string -is "4,\-5,\-3,3". - -To exit from bootloade and run the application program, the sequence is: -put GPIO_4="low"; then send reset pulse. -The corresponding string for -.I GPIO_string -is "\-4,\-3,3". - -The complete command line flag is "\-i 4,\-5,\-3,3:\-4,\-3,3". - -STM32W uses pad PA5 to select boot mode; if during reset PA5 is "low" then -STM32W will enter in bootloader mode; if PA5 is "high" it will execute the -program in flash. - -As example, supposing GPIO_3 connected to PA5 and GPIO_2 to STM32W's reset. -The command: -.PD 0 -.RS -stm32flash \-i \-3,\-2,2:3,\-2,2 /dev/ttyS0 -.RE -provides: -.IP \(bu 2 -entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high -.IP \(bu 2 -exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high -.PD - -.SH EXAMPLES -Get device information: -.RS -.PD 0 -.P -stm32flash /dev/ttyS0 -.PD -.RE - -Write with verify and then start execution: -.RS -.PD 0 -.P -stm32flash \-w filename \-v \-g 0x0 /dev/ttyS0 -.PD -.RE - -Read flash to file: -.RS -.PD 0 -.P -stm32flash \-r filename /dev/ttyS0 -.PD -.RE - -Start execution: -.RS -.PD 0 -.P -stm32flash \-g 0x0 /dev/ttyS0 -.PD -.RE - -Specify: -.PD 0 -.IP \(bu 2 -entry sequence: RTS=low, DTR=low, DTR=high -.IP \(bu 2 -exit sequence: RTS=high, DTR=low, DTR=high -.P -.RS -stm32flash \-i \-rts,\-dtr,dtr:rts,\-dtr,dtr /dev/ttyS0 -.PD -.RE - -.SH FORMAT CONVERSION -Flash images provided by ST or created with ST tools are often in file -format Motorola S\-Record. -Conversion between raw binary, intel hex and Motorola S\-Record can be -done through software package SRecord. - -.SH AUTHORS -The original software package -.B stm32flash -is written by -.I Geoffrey McRae -and is since 2012 maintained by -.IR "Tormod Volden " . - -Man page and extension to STM32W and I2C are written by -.IR "Antonio Borneo " . - -Please report any bugs at the project homepage -http://stm32flash.googlecode.com . - -.SH SEE ALSO -.BR "srec_cat" "(1)," " srec_intel" "(5)," " srec_motorola" "(5)." - -The communication protocol used by ST bootloader is documented in -following ST application notes, depending on communication port. -The current version of -.B stm32flash -only supports -.I UART -and -.I I2C -ports. -.PD 0 -.P -.IP \(bu 2 -AN3154: CAN protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/CD00264321.pdf -.RE - -.P -.IP \(bu 2 -AN3155: USART protocol used in the STM32(TM) bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/CD00264342.pdf -.RE - -.P -.IP \(bu 2 -AN4221: I2C protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/DM00072315.pdf -.RE - -.P -.IP \(bu 2 -AN4286: SPI protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/DM00081379.pdf -.RE - -.PD - - -Boot mode selection for STM32 is documented in ST application note -AN2606, available from the ST website: -.PD 0 -.P -http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf -.PD - -.SH LICENSE -.B stm32flash -is distributed under GNU GENERAL PUBLIC LICENSE Version 2. -Copy of the license is available within the source code in the file -.IR "gpl\-2.0.txt" . diff --git a/macosx/src/stm32flash_serial/src/utils.c b/macosx/src/stm32flash_serial/src/utils.c deleted file mode 100644 index 271bb3ed7..000000000 --- a/macosx/src/stm32flash_serial/src/utils.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include "utils.h" - -/* detect CPU endian */ -char cpu_le() { - const uint32_t cpu_le_test = 0x12345678; - return ((const unsigned char*)&cpu_le_test)[0] == 0x78; -} - -uint32_t be_u32(const uint32_t v) { - if (cpu_le()) - return ((v & 0xFF000000) >> 24) | - ((v & 0x00FF0000) >> 8) | - ((v & 0x0000FF00) << 8) | - ((v & 0x000000FF) << 24); - return v; -} - -uint32_t le_u32(const uint32_t v) { - if (!cpu_le()) - return ((v & 0xFF000000) >> 24) | - ((v & 0x00FF0000) >> 8) | - ((v & 0x0000FF00) << 8) | - ((v & 0x000000FF) << 24); - return v; -} diff --git a/macosx/src/stm32flash_serial/src/utils.h b/macosx/src/stm32flash_serial/src/utils.h deleted file mode 100644 index a8d37d2d5..000000000 --- a/macosx/src/stm32flash_serial/src/utils.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_UTILS -#define _H_UTILS - -#include - -char cpu_le(); -uint32_t be_u32(const uint32_t v); -uint32_t le_u32(const uint32_t v); - -#endif diff --git a/macosx/stm32flash/stm32flash b/macosx/stm32flash/stm32flash index dc8d42241..8176d233e 100755 Binary files a/macosx/stm32flash/stm32flash and b/macosx/stm32flash/stm32flash differ diff --git a/win/src/stm32flash_serial/src/AUTHORS b/win/src/stm32flash_serial/src/AUTHORS deleted file mode 100644 index d096f2205..000000000 --- a/win/src/stm32flash_serial/src/AUTHORS +++ /dev/null @@ -1,19 +0,0 @@ -Authors ordered by first contribution. - -Geoffrey McRae -Bret Olmsted -Tormod Volden -Jakob Malm -Reuben Dowle -Matthias Kubisch -Paul Fertser -Daniel Strnad -Jérémie Rapin -Christian Pointner -Mats Erik Andersson -Alexey Borovik -Antonio Borneo -Armin van der Togt -Brian Silverman -Georg Hofmann -Luis Rodrigues diff --git a/win/src/stm32flash_serial/src/Android.mk b/win/src/stm32flash_serial/src/Android.mk deleted file mode 100644 index 7be3d0018..000000000 --- a/win/src/stm32flash_serial/src/Android.mk +++ /dev/null @@ -1,20 +0,0 @@ -TOP_LOCAL_PATH := $(call my-dir) - -include $(call all-named-subdir-makefiles, parsers) - -LOCAL_PATH := $(TOP_LOCAL_PATH) - -include $(CLEAR_VARS) -LOCAL_MODULE := stm32flash -LOCAL_SRC_FILES := \ - dev_table.c \ - i2c.c \ - init.c \ - main.c \ - port.c \ - serial_common.c \ - serial_platform.c \ - stm32.c \ - utils.c -LOCAL_STATIC_LIBRARIES := libparsers -include $(BUILD_EXECUTABLE) diff --git a/win/src/stm32flash_serial/src/HOWTO b/win/src/stm32flash_serial/src/HOWTO deleted file mode 100644 index d8f32eb04..000000000 --- a/win/src/stm32flash_serial/src/HOWTO +++ /dev/null @@ -1,35 +0,0 @@ -Add new interfaces: -===================================================================== -Current version 0.4 supports the following interfaces: -- UART Windows (either "COMn" and "\\.\COMn"); -- UART posix/Linux (e.g. "/dev/ttyUSB0"); -- I2C Linux through standard driver "i2c-dev" (e.g. "/dev/i2c-n"). - -Starting from version 0.4, the back-end of stm32flash is modular and -ready to be expanded to support new interfaces. -I'm planning adding SPI on Linux through standard driver "spidev". -You are invited to contribute with more interfaces. - -To add a new interface you need to add a new file, populate the struct -port_interface (check at the end of files i2c.c, serial_posix.c and -serial_w32.c) and provide the relative functions to operate on the -interface: open/close, read/write, get_cfg_str and the optional gpio. -The include the new drive in Makefile and register the new struct -port_interface in file port.c in struct port_interface *ports[]. - -There are several USB-I2C adapter in the market, each providing its -own libraries to communicate with the I2C bus. -Could be interesting to provide as back-end a bridge between stm32flash -and such libraries (I have no plan on this item). - - -Add new STM32 devices: -===================================================================== -Add a new line in file dev_table.c, in table devices[]. -The fields of the table are listed in stm32.h, struct stm32_dev. - - -Cross compile on Linux host for Windows target with MinGW: -===================================================================== -I'm using a 64 bit Arch Linux machines, and I usually run: - make CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar diff --git a/win/src/stm32flash_serial/src/I2C.txt b/win/src/stm32flash_serial/src/I2C.txt deleted file mode 100644 index 4c05ff62d..000000000 --- a/win/src/stm32flash_serial/src/I2C.txt +++ /dev/null @@ -1,94 +0,0 @@ -About I2C back-end communication in stm32flash -========================================================================== - -Starting from version v0.4, beside the serial communication port, -stm32flash adds support for I2C port to talk with STM32 bootloader. - -The current I2C back-end supports only the API provided by Linux kernel -driver "i2c-dev", so only I2C controllers with Linux kernel driver can be -used. -In Linux source code, most of the drivers for I2C and SMBUS controllers -are in - ./drivers/i2c/busses/ -Only I2C is supported by STM32 bootloader, so check the section below -about SMBUS. -No I2C support for Windows is available in stm32flash v0.4. - -Thanks to the new modular back-end, stm32flash can be easily extended to -support new back-ends and API. Check HOWTO file in stm32flash source code -for details. - -In the market there are several USB-to-I2C dongles; most of them are not -supported by kernel drivers. Manufacturer provide proprietary userspace -libraries using not standardized API. -These API and dongles could be supported in feature versions. - -There are currently 3 versions of STM32 bootloader for I2C communications: -- v1.0 using I2C clock stretching synchronization between host and STM32; -- v1.1 superset of v1.0, adds non stretching commands; -- v1.2 superset of v1.1, adds CRC command and compatibility with i2cdetect. -Details in ST application note AN2606. -All the bootloaders above are tested and working with stm32flash. - - -SMBUS controllers -========================================================================== - -Almost 50% of the drivers in Linux source code folder - ./drivers/i2c/busses/ -are for controllers that "only" support SMBUS protocol. They can NOT -operate with STM32 bootloader. -To identify if your controller supports I2C, use command: - i2cdetect -F n -where "n" is the number of the I2C interface (e.g. n=3 for "/dev/i2c-3"). -Controllers that supports I2C will report - I2C yes -Controller that support both I2C and SMBUS are ok. - -If you are interested on details about SMBUS protocol, you can download -the current specs from - http://smbus.org/specs/smbus20.pdf -and you can read the files in Linux source code - ./Documentation/i2c/i2c-protocol - ./Documentation/i2c/smbus-protocol - - -About bootloader v1.0 -========================================================================== - -Version v1.0 can have issues with some I2C controllers due to use of clock -stretching during commands that require long operations, like flash erase -and programming. - -Clock stretching is a technique to synchronize host and I2C device. When -I2C device wants to force a delay in the communication, it push "low" the -I2C clock; the I2C controller detects it and waits until I2C clock returns -"high". -Most I2C controllers set a "timeout" for clock stretching, ranging from -few milli-seconds to seconds depending on specific HW or SW driver. - -It is possible that the timeout in your I2C controller is smaller than the -delay required for flash erase or programming. In this case the I2C -controller will timeout and report error to stm32flash. -There is no possibility for stm32flash to retry, so it can only signal the -error and exit. - -To by-pass the issue with bootloader v1.0 you can modify the kernel driver -of your I2C controller. Not an easy job, since every controller has its own -way to handle the timeout. - -In my case I'm using the I2C controller integrated in the VGA port of my -laptop HP EliteBook 8460p. I built the 0.25$ VGA-to-I2C adapter reported in - http://www.paintyourdragon.com/?p=43 -To change the timeout of the I2C controller I had to modify the kernel file - drivers/gpu/drm/radeon/radeon_i2c.c -line 969 -- i2c->bit.timeout = usecs_to_jiffies(2200); /* from VESA */ -+ i2c->bit.timeout = msecs_to_jiffies(5000); /* 5s for STM32 */ -and recompile it. -Then - $> modprobe i2c-dev - $> chmod 666 /dev/i2c-7 - #> stm32flash -a 0x39 /dev/i2c-7 - -2014-09-16 Antonio Borneo diff --git a/win/src/stm32flash_serial/src/Makefile b/win/src/stm32flash_serial/src/Makefile deleted file mode 100644 index 0328d5588..000000000 --- a/win/src/stm32flash_serial/src/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -PREFIX = /usr/local -CFLAGS += -Wall -g - -INSTALL = install - -OBJS = dev_table.o \ - i2c.o \ - init.o \ - main.o \ - port.o \ - serial_common.o \ - serial_platform.o \ - stm32.o \ - utils.o - -LIBOBJS = parsers/parsers.a - -all: stm32flash - -serial_platform.o: serial_posix.c serial_w32.c - -parsers/parsers.a: - cd parsers && $(MAKE) parsers.a - -stm32flash: $(OBJS) $(LIBOBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBOBJS) - -clean: - rm -f $(OBJS) stm32flash - cd parsers && $(MAKE) $@ - -install: all - $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin - $(INSTALL) -m 755 stm32flash $(DESTDIR)$(PREFIX)/bin - $(INSTALL) -d $(DESTDIR)$(PREFIX)/share/man/man1 - $(INSTALL) -m 644 stm32flash.1 $(DESTDIR)$(PREFIX)/share/man/man1 - -.PHONY: all clean install diff --git a/win/src/stm32flash_serial/src/TODO b/win/src/stm32flash_serial/src/TODO deleted file mode 100644 index 41df614ff..000000000 --- a/win/src/stm32flash_serial/src/TODO +++ /dev/null @@ -1,7 +0,0 @@ - -stm32: -- Add support for variable page size - -AUTHORS: -- Add contributors from Geoffrey's commits - diff --git a/win/src/stm32flash_serial/src/dev_table.c b/win/src/stm32flash_serial/src/dev_table.c deleted file mode 100644 index 399cd9d08..000000000 --- a/win/src/stm32flash_serial/src/dev_table.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "stm32.h" - -/* - * Device table, corresponds to the "Bootloader device-dependant parameters" - * table in ST document AN2606. - * Note that the option bytes upper range is inclusive! - */ -const stm32_dev_t devices[] = { - /* F0 */ - {0x440, "STM32F051xx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, - {0x444, "STM32F030/F031" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, - {0x445, "STM32F042xx" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, - {0x448, "STM32F072xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, - /* F1 */ - {0x412, "Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x410, "Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x414, "High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x420, "Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x428, "High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x418, "Connectivity line" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, - {0x430, "XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, - /* Note that F2 and F4 devices have sectors of different page sizes - and only the first sectors (of one page size) are included here */ - /* F2 */ - {0x411, "STM32F2xx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, - /* F3 */ - {0x432, "STM32F373/8" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x422, "F302xB/303xB/358" , 0x20001400, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x439, "STM32F302x4(6/8)" , 0x20001800, 0x20004000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x438, "F303x4/334/328" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - /* F4 */ - {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, - /* 0x419 is also used for STM32F429/39 but with other bootloader ID... */ - {0x419, "STM32F427/37" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - /* L0 */ - {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - /* L1 */ - {0x416, "L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x429, "L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x427, "L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, - {0x436, "L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - {0x437, "L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - /* These are not (yet) in AN2606: */ - {0x641, "Medium_Density PL" , 0x20000200, 0x00005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, - {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 1, 2048, 0, 0, 0, 0}, - {0x0} -}; diff --git a/win/src/stm32flash_serial/src/gpl-2.0.txt b/win/src/stm32flash_serial/src/gpl-2.0.txt deleted file mode 100644 index d159169d1..000000000 --- a/win/src/stm32flash_serial/src/gpl-2.0.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/win/src/stm32flash_serial/src/i2c.c b/win/src/stm32flash_serial/src/i2c.c deleted file mode 100644 index 10e6bb15a..000000000 --- a/win/src/stm32flash_serial/src/i2c.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - - -#if !defined(__linux__) - -static port_err_t i2c_open(struct port_interface *port, - struct port_options *ops) -{ - return PORT_ERR_NODEV; -} - -struct port_interface port_i2c = { - .name = "i2c", - .open = i2c_open, -}; - -#else - -#ifdef __ANDROID__ -#define I2C_SLAVE 0x0703 /* Use this slave address */ -#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */ -/* To determine what functionality is present */ -#define I2C_FUNC_I2C 0x00000001 -#else -#include -#include -#endif - -#include - -struct i2c_priv { - int fd; - int addr; -}; - -static port_err_t i2c_open(struct port_interface *port, - struct port_options *ops) -{ - struct i2c_priv *h; - int fd, addr, ret; - unsigned long funcs; - - /* 1. check device name match */ - if (strncmp(ops->device, "/dev/i2c-", strlen("/dev/i2c-"))) - return PORT_ERR_NODEV; - - /* 2. check options */ - addr = ops->bus_addr; - if (addr < 0x03 || addr > 0x77) { - fprintf(stderr, "I2C address out of range [0x03-0x77]\n"); - return PORT_ERR_UNKNOWN; - } - - /* 3. open it */ - h = calloc(sizeof(*h), 1); - if (h == NULL) { - fprintf(stderr, "End of memory\n"); - return PORT_ERR_UNKNOWN; - } - fd = open(ops->device, O_RDWR); - if (fd < 0) { - fprintf(stderr, "Unable to open special file \"%s\"\n", - ops->device); - free(h); - return PORT_ERR_UNKNOWN; - } - - /* 3.5. Check capabilities */ - ret = ioctl(fd, I2C_FUNCS, &funcs); - if (ret < 0) { - fprintf(stderr, "I2C ioctl(funcs) error %d\n", errno); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - if ((funcs & I2C_FUNC_I2C) == 0) { - fprintf(stderr, "Error: controller is not I2C, only SMBUS.\n"); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - - /* 4. set options */ - ret = ioctl(fd, I2C_SLAVE, addr); - if (ret < 0) { - fprintf(stderr, "I2C ioctl(slave) error %d\n", errno); - close(fd); - free(h); - return PORT_ERR_UNKNOWN; - } - - h->fd = fd; - h->addr = addr; - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t i2c_close(struct port_interface *port) -{ - struct i2c_priv *h; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - close(h->fd); - free(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t i2c_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - struct i2c_priv *h; - int ret; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - ret = read(h->fd, buf, nbyte); - if (ret != nbyte) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; -} - -static port_err_t i2c_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - struct i2c_priv *h; - int ret; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - ret = write(h->fd, buf, nbyte); - if (ret != nbyte) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; -} - -static port_err_t i2c_gpio(struct port_interface *port, serial_gpio_t n, - int level) -{ - return PORT_ERR_OK; -} - -static const char *i2c_get_cfg_str(struct port_interface *port) -{ - struct i2c_priv *h; - static char str[11]; - - h = (struct i2c_priv *)port->private; - if (h == NULL) - return "INVALID"; - snprintf(str, sizeof(str), "addr 0x%2x", h->addr); - return str; -} - -static struct varlen_cmd i2c_cmd_get_reply[] = { - {0x10, 11}, - {0x11, 17}, - {0x12, 18}, - { /* sentinel */ } -}; - -struct port_interface port_i2c = { - .name = "i2c", - .flags = PORT_STRETCH_W, - .open = i2c_open, - .close = i2c_close, - .read = i2c_read, - .write = i2c_write, - .gpio = i2c_gpio, - .cmd_get_reply = i2c_cmd_get_reply, - .get_cfg_str = i2c_get_cfg_str, -}; - -#endif diff --git a/win/src/stm32flash_serial/src/init.c b/win/src/stm32flash_serial/src/init.c deleted file mode 100644 index 77a571bd8..000000000 --- a/win/src/stm32flash_serial/src/init.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include "init.h" -#include "serial.h" -#include "stm32.h" -#include "port.h" - -struct gpio_list { - struct gpio_list *next; - int gpio; -}; - - -static int write_to(const char *filename, const char *value) -{ - int fd, ret; - - fd = open(filename, O_WRONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open file \"%s\"\n", filename); - return 0; - } - ret = write(fd, value, strlen(value)); - if (ret < 0) { - fprintf(stderr, "Error writing in file \"%s\"\n", filename); - close(fd); - return 0; - } - close(fd); - return 1; -} - -#if !defined(__linux__) -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) -{ - fprintf(stderr, "GPIO control only available in Linux\n"); - return 0; -} -#else -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) -{ - char num[16]; /* sized to carry MAX_INT */ - char file[48]; /* sized to carry longest filename */ - struct stat buf; - struct gpio_list *new; - int ret; - - sprintf(file, "/sys/class/gpio/gpio%d/direction", n); - ret = stat(file, &buf); - if (ret) { - /* file miss, GPIO not exported yet */ - sprintf(num, "%d", n); - ret = write_to("/sys/class/gpio/export", num); - if (!ret) - return 0; - ret = stat(file, &buf); - if (ret) { - fprintf(stderr, "GPIO %d not available\n", n); - return 0; - } - new = (struct gpio_list *)malloc(sizeof(struct gpio_list)); - if (new == NULL) { - fprintf(stderr, "Out of memory\n"); - return 0; - } - new->gpio = n; - new->next = *gpio_to_release; - *gpio_to_release = new; - } - - return write_to(file, level ? "high" : "low"); -} -#endif - -static int release_gpio(int n) -{ - char num[16]; /* sized to carry MAX_INT */ - - sprintf(num, "%d", n); - return write_to("/sys/class/gpio/unexport", num); -} - -static int gpio_sequence(struct port_interface *port, const char *s, size_t l) -{ - struct gpio_list *gpio_to_release = NULL, *to_free; - int ret, level, gpio; - - ret = 1; - while (ret == 1 && *s && l > 0) { - if (*s == '-') { - level = 0; - s++; - l--; - } else - level = 1; - - if (isdigit(*s)) { - gpio = atoi(s); - while (isdigit(*s)) { - s++; - l--; - } - } else if (!strncmp(s, "rts", 3)) { - gpio = -GPIO_RTS; - s += 3; - l -= 3; - } else if (!strncmp(s, "dtr", 3)) { - gpio = -GPIO_DTR; - s += 3; - l -= 3; - } else if (!strncmp(s, "brk", 3)) { - gpio = -GPIO_BRK; - s += 3; - l -= 3; - } else { - fprintf(stderr, "Character \'%c\' is not a digit\n", *s); - ret = 0; - break; - } - - if (*s && (l > 0)) { - if (*s == ',') { - s++; - l--; - } else { - fprintf(stderr, "Character \'%c\' is not a separator\n", *s); - ret = 0; - break; - } - } - if (gpio < 0) - ret = (port->gpio(port, -gpio, level) == PORT_ERR_OK); - else - ret = drive_gpio(gpio, level, &gpio_to_release); - usleep(100000); - } - - while (gpio_to_release) { - release_gpio(gpio_to_release->gpio); - to_free = gpio_to_release; - gpio_to_release = gpio_to_release->next; - free(to_free); - } - usleep(500000); - return ret; -} - -static int gpio_bl_entry(struct port_interface *port, const char *seq) -{ - char *s; - - if (seq == NULL || seq[0] == ':') - return 1; - - s = strchr(seq, ':'); - if (s == NULL) - return gpio_sequence(port, seq, strlen(seq)); - - return gpio_sequence(port, seq, s - seq); -} - -static int gpio_bl_exit(struct port_interface *port, const char *seq) -{ - char *s; - - if (seq == NULL) - return 1; - - s = strchr(seq, ':'); - if (s == NULL || s[1] == '\0') - return 1; - - return gpio_sequence(port, s + 1, strlen(s + 1)); -} - -int init_bl_entry(struct port_interface *port, const char *seq) -{ - if (seq) - return gpio_bl_entry(port, seq); - - return 1; -} - -int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq) -{ - if (seq) - return gpio_bl_exit(port, seq); - - if (stm32_reset_device(stm) != STM32_ERR_OK) - return 0; - return 1; -} diff --git a/win/src/stm32flash_serial/src/init.h b/win/src/stm32flash_serial/src/init.h deleted file mode 100644 index 6075b519b..000000000 --- a/win/src/stm32flash_serial/src/init.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _INIT_H -#define _INIT_H - -#include "stm32.h" -#include "port.h" - -int init_bl_entry(struct port_interface *port, const char *seq); -int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq); - -#endif diff --git a/win/src/stm32flash_serial/src/main.c b/win/src/stm32flash_serial/src/main.c deleted file mode 100644 index f081d6131..000000000 --- a/win/src/stm32flash_serial/src/main.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright 2010 Geoffrey McRae - Copyright 2011 Steve Markgraf - Copyright 2012 Tormod Volden - Copyright 2013 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "init.h" -#include "utils.h" -#include "serial.h" -#include "stm32.h" -#include "parsers/parser.h" -#include "port.h" - -#include "parsers/binary.h" -#include "parsers/hex.h" - -#define VERSION "Arduino_STM32_0.9" - -/* device globals */ -stm32_t *stm = NULL; - -void *p_st = NULL; -parser_t *parser = NULL; - -/* settings */ -struct port_options port_opts = { - .device = NULL, - .baudRate = SERIAL_BAUD_57600, - .serial_mode = "8e1", - .bus_addr = 0, - .rx_frame_max = STM32_MAX_RX_FRAME, - .tx_frame_max = STM32_MAX_TX_FRAME, -}; -int rd = 0; -int wr = 0; -int wu = 0; -int rp = 0; -int ur = 0; -int eraseOnly = 0; -int crc = 0; -int npages = 0; -int spage = 0; -int no_erase = 0; -char verify = 0; -int retry = 10; -char exec_flag = 0; -uint32_t execute = 0; -char init_flag = 1; -char force_binary = 0; -char reset_flag = 0; -char *filename; -char *gpio_seq = NULL; -uint32_t start_addr = 0; -uint32_t readwrite_len = 0; - -/* functions */ -int parse_options(int argc, char *argv[]); -void show_help(char *name); - -static int is_addr_in_ram(uint32_t addr) -{ - return addr >= stm->dev->ram_start && addr < stm->dev->ram_end; -} - -static int is_addr_in_flash(uint32_t addr) -{ - return addr >= stm->dev->fl_start && addr < stm->dev->fl_end; -} - -static int flash_addr_to_page_floor(uint32_t addr) -{ - if (!is_addr_in_flash(addr)) - return 0; - - return (addr - stm->dev->fl_start) / stm->dev->fl_ps; -} - -static int flash_addr_to_page_ceil(uint32_t addr) -{ - if (!(addr >= stm->dev->fl_start && addr <= stm->dev->fl_end)) - return 0; - - return (addr + stm->dev->fl_ps - 1 - stm->dev->fl_start) - / stm->dev->fl_ps; -} - -static uint32_t flash_page_to_addr(int page) -{ - return stm->dev->fl_start + page * stm->dev->fl_ps; -} - -int main(int argc, char* argv[]) { - struct port_interface *port = NULL; - int ret = 1; - stm32_err_t s_err; - parser_err_t perr; - FILE *diag = stdout; - - fprintf(diag, "stm32flash " VERSION "\n\n"); - fprintf(diag, "http://github.com/rogerclarkmelbourne/arduino_stm32\n\n"); - if (parse_options(argc, argv) != 0) - goto close; - - if (rd && filename[0] == '-') { - diag = stderr; - } - - if (wr) { - /* first try hex */ - if (!force_binary) { - parser = &PARSER_HEX; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - } - - if (force_binary || (perr = parser->open(p_st, filename, 0)) != PARSER_ERR_OK) { - if (force_binary || perr == PARSER_ERR_INVALID_FILE) { - if (!force_binary) { - parser->close(p_st); - p_st = NULL; - } - - /* now try binary */ - parser = &PARSER_BINARY; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - perr = parser->open(p_st, filename, 0); - } - - /* if still have an error, fail */ - if (perr != PARSER_ERR_OK) { - fprintf(stderr, "%s ERROR: %s\n", parser->name, parser_errstr(perr)); - if (perr == PARSER_ERR_SYSTEM) perror(filename); - goto close; - } - } - - fprintf(diag, "Using Parser : %s\n", parser->name); - } else { - parser = &PARSER_BINARY; - p_st = parser->init(); - if (!p_st) { - fprintf(stderr, "%s Parser failed to initialize\n", parser->name); - goto close; - } - } - - if (port_open(&port_opts, &port) != PORT_ERR_OK) { - fprintf(stderr, "Failed to open port: %s\n", port_opts.device); - goto close; - } - - fprintf(diag, "Interface %s: %s\n", port->name, port->get_cfg_str(port)); - if (init_flag && init_bl_entry(port, gpio_seq) == 0) - goto close; - stm = stm32_init(port, init_flag); - if (!stm) - goto close; - - fprintf(diag, "Version : 0x%02x\n", stm->bl_version); - if (port->flags & PORT_GVR_ETX) { - fprintf(diag, "Option 1 : 0x%02x\n", stm->option1); - fprintf(diag, "Option 2 : 0x%02x\n", stm->option2); - } - fprintf(diag, "Device ID : 0x%04x (%s)\n", stm->pid, stm->dev->name); - fprintf(diag, "- RAM : %dKiB (%db reserved by bootloader)\n", (stm->dev->ram_end - 0x20000000) / 1024, stm->dev->ram_start - 0x20000000); - fprintf(diag, "- Flash : %dKiB (sector size: %dx%d)\n", (stm->dev->fl_end - stm->dev->fl_start ) / 1024, stm->dev->fl_pps, stm->dev->fl_ps); - fprintf(diag, "- Option RAM : %db\n", stm->dev->opt_end - stm->dev->opt_start + 1); - fprintf(diag, "- System RAM : %dKiB\n", (stm->dev->mem_end - stm->dev->mem_start) / 1024); - - uint8_t buffer[256]; - uint32_t addr, start, end; - unsigned int len; - int failed = 0; - int first_page, num_pages; - - /* - * Cleanup addresses: - * - * Starting from options - * start_addr, readwrite_len, spage, npages - * and using device memory size, compute - * start, end, first_page, num_pages - */ - if (start_addr || readwrite_len) { - start = start_addr; - - if (is_addr_in_flash(start)) - end = stm->dev->fl_end; - else { - no_erase = 1; - if (is_addr_in_ram(start)) - end = stm->dev->ram_end; - else - end = start + sizeof(uint32_t); - } - - if (readwrite_len && (end > start + readwrite_len)) - end = start + readwrite_len; - - first_page = flash_addr_to_page_floor(start); - if (!first_page && end == stm->dev->fl_end) - num_pages = 0xff; /* mass erase */ - else - num_pages = flash_addr_to_page_ceil(end) - first_page; - } else if (!spage && !npages) { - start = stm->dev->fl_start; - end = stm->dev->fl_end; - first_page = 0; - num_pages = 0xff; /* mass erase */ - } else { - first_page = spage; - start = flash_page_to_addr(first_page); - if (start > stm->dev->fl_end) { - fprintf(stderr, "Address range exceeds flash size.\n"); - goto close; - } - - if (npages) { - num_pages = npages; - end = flash_page_to_addr(first_page + num_pages); - if (end > stm->dev->fl_end) - end = stm->dev->fl_end; - } else { - end = stm->dev->fl_end; - num_pages = flash_addr_to_page_ceil(end) - first_page; - } - - if (!first_page && end == stm->dev->fl_end) - num_pages = 0xff; /* mass erase */ - } - - if (rd) { - unsigned int max_len = port_opts.rx_frame_max; - - fprintf(diag, "Memory read\n"); - - perr = parser->open(p_st, filename, 1); - if (perr != PARSER_ERR_OK) { - fprintf(stderr, "%s ERROR: %s\n", parser->name, parser_errstr(perr)); - if (perr == PARSER_ERR_SYSTEM) - perror(filename); - goto close; - } - - fflush(diag); - addr = start; - while(addr < end) { - uint32_t left = end - addr; - len = max_len > left ? left : max_len; - s_err = stm32_read_memory(stm, addr, buffer, len); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read memory at address 0x%08x, target write-protected?\n", addr); - goto close; - } - if (parser->write(p_st, buffer, len) != PARSER_ERR_OK) - { - fprintf(stderr, "Failed to write data to file\n"); - goto close; - } - addr += len; - - fprintf(diag, - "\rRead address 0x%08x (%.2f%%) ", - addr, - (100.0f / (float)(end - start)) * (float)(addr - start) - ); - fflush(diag); - } - fprintf(diag, "Done.\n"); - ret = 0; - goto close; - } else if (rp) { - fprintf(stdout, "Read-Protecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_readprot_memory(stm); - fprintf(stdout, "Done.\n"); - } else if (ur) { - fprintf(stdout, "Read-UnProtecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_runprot_memory(stm); - fprintf(stdout, "Done.\n"); - } else if (eraseOnly) { - ret = 0; - fprintf(stdout, "Erasing flash\n"); - - if (num_pages != 0xff && - (start != flash_page_to_addr(first_page) - || end != flash_page_to_addr(first_page + num_pages))) { - fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); - ret = 1; - goto close; - } - - s_err = stm32_erase_memory(stm, first_page, num_pages); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to erase memory\n"); - ret = 1; - goto close; - } - } else if (wu) { - fprintf(diag, "Write-unprotecting flash\n"); - /* the device automatically performs a reset after the sending the ACK */ - reset_flag = 0; - stm32_wunprot_memory(stm); - fprintf(diag, "Done.\n"); - - } else if (wr) { - fprintf(diag, "Write to memory\n"); - - off_t offset = 0; - ssize_t r; - unsigned int size; - unsigned int max_wlen, max_rlen; - - max_wlen = port_opts.tx_frame_max - 2; /* skip len and crc */ - max_wlen &= ~3; /* 32 bit aligned */ - - max_rlen = port_opts.rx_frame_max; - max_rlen = max_rlen < max_wlen ? max_rlen : max_wlen; - - /* Assume data from stdin is whole device */ - if (filename[0] == '-' && filename[1] == '\0') - size = end - start; - else - size = parser->size(p_st); - - // TODO: It is possible to write to non-page boundaries, by reading out flash - // from partial pages and combining with the input data - // if ((start % stm->dev->fl_ps) != 0 || (end % stm->dev->fl_ps) != 0) { - // fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); - // goto close; - // } - - // TODO: If writes are not page aligned, we should probably read out existing flash - // contents first, so it can be preserved and combined with new data - if (!no_erase && num_pages) { - fprintf(diag, "Erasing memory\n"); - s_err = stm32_erase_memory(stm, first_page, num_pages); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to erase memory\n"); - goto close; - } - } - - fflush(diag); - addr = start; - while(addr < end && offset < size) { - uint32_t left = end - addr; - len = max_wlen > left ? left : max_wlen; - len = len > size - offset ? size - offset : len; - - if (parser->read(p_st, buffer, &len) != PARSER_ERR_OK) - goto close; - - if (len == 0) { - if (filename[0] == '-') { - break; - } else { - fprintf(stderr, "Failed to read input file\n"); - goto close; - } - } - - again: - s_err = stm32_write_memory(stm, addr, buffer, len); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to write memory at address 0x%08x\n", addr); - goto close; - } - - if (verify) { - uint8_t compare[len]; - unsigned int offset, rlen; - - offset = 0; - while (offset < len) { - rlen = len - offset; - rlen = rlen < max_rlen ? rlen : max_rlen; - s_err = stm32_read_memory(stm, addr + offset, compare + offset, rlen); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read memory at address 0x%08x\n", addr + offset); - goto close; - } - offset += rlen; - } - - for(r = 0; r < len; ++r) - if (buffer[r] != compare[r]) { - if (failed == retry) { - fprintf(stderr, "Failed to verify at address 0x%08x, expected 0x%02x and found 0x%02x\n", - (uint32_t)(addr + r), - buffer [r], - compare[r] - ); - goto close; - } - ++failed; - goto again; - } - - failed = 0; - } - - addr += len; - offset += len; - - fprintf(diag, - "\rWrote %saddress 0x%08x (%.2f%%) ", - verify ? "and verified " : "", - addr, - (100.0f / size) * offset - ); - fflush(diag); - - } - - fprintf(diag, "Done.\n"); - ret = 0; - goto close; - } else if (crc) { - uint32_t crc_val = 0; - - fprintf(diag, "CRC computation\n"); - - s_err = stm32_crc_wrapper(stm, start, end - start, &crc_val); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read CRC\n"); - goto close; - } - fprintf(diag, "CRC(0x%08x-0x%08x) = 0x%08x\n", start, end, - crc_val); - ret = 0; - goto close; - } else - ret = 0; - -close: - if (stm && exec_flag && ret == 0) { - if (execute == 0) - execute = stm->dev->fl_start; - - fprintf(diag, "\nStarting execution at address 0x%08x... ", execute); - fflush(diag); - if (stm32_go(stm, execute) == STM32_ERR_OK) { - reset_flag = 0; - fprintf(diag, "done.\n"); - } else - fprintf(diag, "failed.\n"); - } - - if (stm && reset_flag) { - fprintf(diag, "\nResetting device... "); - fflush(diag); - if (init_bl_exit(stm, port, gpio_seq)) - fprintf(diag, "done.\n"); - else fprintf(diag, "failed.\n"); - } - - if (p_st ) parser->close(p_st); - if (stm ) stm32_close (stm); - if (port) - port->close(port); - - fprintf(diag, "\n"); - return ret; -} - -int parse_options(int argc, char *argv[]) -{ - int c; - char *pLen; - - while ((c = getopt(argc, argv, "a:b:m:r:w:e:vn:g:jkfcChuos:S:F:i:R")) != -1) { - switch(c) { - case 'a': - port_opts.bus_addr = strtoul(optarg, NULL, 0); - break; - - case 'b': - port_opts.baudRate = serial_get_baud(strtoul(optarg, NULL, 0)); - if (port_opts.baudRate == SERIAL_BAUD_INVALID) { - serial_baud_t baudrate; - fprintf(stderr, "Invalid baud rate, valid options are:\n"); - for (baudrate = SERIAL_BAUD_1200; baudrate != SERIAL_BAUD_INVALID; ++baudrate) - fprintf(stderr, " %d\n", serial_get_baud_int(baudrate)); - return 1; - } - break; - - case 'm': - if (strlen(optarg) != 3 - || serial_get_bits(optarg) == SERIAL_BITS_INVALID - || serial_get_parity(optarg) == SERIAL_PARITY_INVALID - || serial_get_stopbit(optarg) == SERIAL_STOPBIT_INVALID) { - fprintf(stderr, "Invalid serial mode\n"); - return 1; - } - port_opts.serial_mode = optarg; - break; - - case 'r': - case 'w': - rd = rd || c == 'r'; - wr = wr || c == 'w'; - if (rd && wr) { - fprintf(stderr, "ERROR: Invalid options, can't read & write at the same time\n"); - return 1; - } - filename = optarg; - if (filename[0] == '-') { - force_binary = 1; - } - break; - case 'e': - if (readwrite_len || start_addr) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } - npages = strtoul(optarg, NULL, 0); - if (npages > 0xFF || npages < 0) { - fprintf(stderr, "ERROR: You need to specify a page count between 0 and 255"); - return 1; - } - if (!npages) - no_erase = 1; - break; - case 'u': - wu = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't write unprotect and read/write at the same time\n"); - return 1; - } - break; - - case 'j': - rp = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't read protect and read/write at the same time\n"); - return 1; - } - break; - - case 'k': - ur = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't read unprotect and read/write at the same time\n"); - return 1; - } - break; - - case 'o': - eraseOnly = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't erase-only and read/write at the same time\n"); - return 1; - } - break; - - case 'v': - verify = 1; - break; - - case 'n': - retry = strtoul(optarg, NULL, 0); - break; - - case 'g': - exec_flag = 1; - execute = strtoul(optarg, NULL, 0); - if (execute % 4 != 0) { - fprintf(stderr, "ERROR: Execution address must be word-aligned\n"); - return 1; - } - break; - case 's': - if (readwrite_len || start_addr) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } - spage = strtoul(optarg, NULL, 0); - break; - case 'S': - if (spage || npages) { - fprintf(stderr, "ERROR: Invalid options, can't specify start page / num pages and start address/length\n"); - return 1; - } else { - start_addr = strtoul(optarg, &pLen, 0); - if (*pLen == ':') { - pLen++; - readwrite_len = strtoul(pLen, NULL, 0); - if (readwrite_len == 0) { - fprintf(stderr, "ERROR: Invalid options, can't specify zero length\n"); - return 1; - } - } - } - break; - case 'F': - port_opts.rx_frame_max = strtoul(optarg, &pLen, 0); - if (*pLen == ':') { - pLen++; - port_opts.tx_frame_max = strtoul(pLen, NULL, 0); - } - if (port_opts.rx_frame_max < 0 - || port_opts.tx_frame_max < 0) { - fprintf(stderr, "ERROR: Invalid negative value for option -F\n"); - return 1; - } - if (port_opts.rx_frame_max == 0) - port_opts.rx_frame_max = STM32_MAX_RX_FRAME; - if (port_opts.tx_frame_max == 0) - port_opts.tx_frame_max = STM32_MAX_TX_FRAME; - if (port_opts.rx_frame_max < 20 - || port_opts.tx_frame_max < 5) { - fprintf(stderr, "ERROR: current code cannot work with small frames.\n"); - fprintf(stderr, "min(RX) = 20, min(TX) = 5\n"); - return 1; - } - if (port_opts.rx_frame_max > STM32_MAX_RX_FRAME) { - fprintf(stderr, "WARNING: Ignore RX length in option -F\n"); - port_opts.rx_frame_max = STM32_MAX_RX_FRAME; - } - if (port_opts.tx_frame_max > STM32_MAX_TX_FRAME) { - fprintf(stderr, "WARNING: Ignore TX length in option -F\n"); - port_opts.tx_frame_max = STM32_MAX_TX_FRAME; - } - break; - case 'f': - force_binary = 1; - break; - - case 'c': - init_flag = 0; - break; - - case 'h': - show_help(argv[0]); - exit(0); - - case 'i': - gpio_seq = optarg; - break; - - case 'R': - reset_flag = 1; - break; - - case 'C': - crc = 1; - break; - } - } - - for (c = optind; c < argc; ++c) { - if (port_opts.device) { - fprintf(stderr, "ERROR: Invalid parameter specified\n"); - show_help(argv[0]); - return 1; - } - port_opts.device = argv[c]; - } - - if (port_opts.device == NULL) { - fprintf(stderr, "ERROR: Device not specified\n"); - show_help(argv[0]); - return 1; - } - - if (!wr && verify) { - fprintf(stderr, "ERROR: Invalid usage, -v is only valid when writing\n"); - show_help(argv[0]); - return 1; - } - - return 0; -} - -void show_help(char *name) { - fprintf(stderr, - "Usage: %s [-bvngfhc] [-[rw] filename] [tty_device | i2c_device]\n" - " -a bus_address Bus address (e.g. for I2C port)\n" - " -b rate Baud rate (default 57600)\n" - " -m mode Serial port mode (default 8e1)\n" - " -r filename Read flash to file (or - stdout)\n" - " -w filename Write flash from file (or - stdout)\n" - " -C Compute CRC of flash content\n" - " -u Disable the flash write-protection\n" - " -j Enable the flash read-protection\n" - " -k Disable the flash read-protection\n" - " -o Erase only\n" - " -e n Only erase n pages before writing the flash\n" - " -v Verify writes\n" - " -n count Retry failed writes up to count times (default 10)\n" - " -g address Start execution at specified address (0 = flash start)\n" - " -S address[:length] Specify start address and optionally length for\n" - " read/write/erase operations\n" - " -F RX_length[:TX_length] Specify the max length of RX and TX frame\n" - " -s start_page Flash at specified page (0 = flash start)\n" - " -f Force binary parser\n" - " -h Show this help\n" - " -c Resume the connection (don't send initial INIT)\n" - " *Baud rate must be kept the same as the first init*\n" - " This is useful if the reset fails\n" - " -i GPIO_string GPIO sequence to enter/exit bootloader mode\n" - " GPIO_string=[entry_seq][:[exit_seq]]\n" - " sequence=[-]n[,sequence]\n" - " -R Reset device at exit.\n" - "\n" - "Examples:\n" - " Get device information:\n" - " %s /dev/ttyS0\n" - " or:\n" - " %s /dev/i2c-0\n" - "\n" - " Write with verify and then start execution:\n" - " %s -w filename -v -g 0x0 /dev/ttyS0\n" - "\n" - " Read flash to file:\n" - " %s -r filename /dev/ttyS0\n" - "\n" - " Read 100 bytes of flash from 0x1000 to stdout:\n" - " %s -r - -S 0x1000:100 /dev/ttyS0\n" - "\n" - " Start execution:\n" - " %s -g 0x0 /dev/ttyS0\n" - "\n" - " GPIO sequence:\n" - " - entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high\n" - " - exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high\n" - " %s -i -3,-2,2:3,-2,2 /dev/ttyS0\n", - name, - name, - name, - name, - name, - name, - name, - name - ); -} - diff --git a/win/src/stm32flash_serial/src/parsers/Android.mk b/win/src/stm32flash_serial/src/parsers/Android.mk deleted file mode 100644 index afec18cd5..000000000 --- a/win/src/stm32flash_serial/src/parsers/Android.mk +++ /dev/null @@ -1,6 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := libparsers -LOCAL_SRC_FILES := binary.c hex.c -include $(BUILD_STATIC_LIBRARY) diff --git a/win/src/stm32flash_serial/src/parsers/Makefile b/win/src/stm32flash_serial/src/parsers/Makefile deleted file mode 100644 index bb7df1e02..000000000 --- a/win/src/stm32flash_serial/src/parsers/Makefile +++ /dev/null @@ -1,12 +0,0 @@ - -CFLAGS += -Wall -g - -all: parsers.a - -parsers.a: binary.o hex.o - $(AR) rc $@ binary.o hex.o - -clean: - rm -f *.o parsers.a - -.PHONY: all clean diff --git a/win/src/stm32flash_serial/src/parsers/binary.c b/win/src/stm32flash_serial/src/parsers/binary.c deleted file mode 100644 index f491952bb..000000000 --- a/win/src/stm32flash_serial/src/parsers/binary.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include - -#include "binary.h" - -typedef struct { - int fd; - char write; - struct stat stat; -} binary_t; - -void* binary_init() { - return calloc(sizeof(binary_t), 1); -} - -parser_err_t binary_open(void *storage, const char *filename, const char write) { - binary_t *st = storage; - if (write) { - if (filename[0] == '-') - st->fd = 1; - else - st->fd = open( - filename, -#ifndef __WIN32__ - O_WRONLY | O_CREAT | O_TRUNC, -#else - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, -#endif -#ifndef __WIN32__ - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH -#else - 0 -#endif - ); - st->stat.st_size = 0; - } else { - if (filename[0] == '-') { - st->fd = 0; - } else { - if (stat(filename, &st->stat) != 0) - return PARSER_ERR_INVALID_FILE; - st->fd = open(filename, -#ifndef __WIN32__ - O_RDONLY -#else - O_RDONLY | O_BINARY -#endif - ); - } - } - - st->write = write; - return st->fd == -1 ? PARSER_ERR_SYSTEM : PARSER_ERR_OK; -} - -parser_err_t binary_close(void *storage) { - binary_t *st = storage; - - if (st->fd) close(st->fd); - free(st); - return PARSER_ERR_OK; -} - -unsigned int binary_size(void *storage) { - binary_t *st = storage; - return st->stat.st_size; -} - -parser_err_t binary_read(void *storage, void *data, unsigned int *len) { - binary_t *st = storage; - unsigned int left = *len; - if (st->write) return PARSER_ERR_WRONLY; - - ssize_t r; - while(left > 0) { - r = read(st->fd, data, left); - /* If there is no data to read at all, return OK, but with zero read */ - if (r == 0 && left == *len) { - *len = 0; - return PARSER_ERR_OK; - } - if (r <= 0) return PARSER_ERR_SYSTEM; - left -= r; - data += r; - } - - *len = *len - left; - return PARSER_ERR_OK; -} - -parser_err_t binary_write(void *storage, void *data, unsigned int len) { - binary_t *st = storage; - if (!st->write) return PARSER_ERR_RDONLY; - - ssize_t r; - while(len > 0) { - r = write(st->fd, data, len); - if (r < 1) return PARSER_ERR_SYSTEM; - st->stat.st_size += r; - - len -= r; - data += r; - } - - return PARSER_ERR_OK; -} - -parser_t PARSER_BINARY = { - "Raw BINARY", - binary_init, - binary_open, - binary_close, - binary_size, - binary_read, - binary_write -}; - diff --git a/win/src/stm32flash_serial/src/parsers/binary.h b/win/src/stm32flash_serial/src/parsers/binary.h deleted file mode 100644 index d989acfa0..000000000 --- a/win/src/stm32flash_serial/src/parsers/binary.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _PARSER_BINARY_H -#define _PARSER_BINARY_H - -#include "parser.h" - -extern parser_t PARSER_BINARY; -#endif diff --git a/win/src/stm32flash_serial/src/parsers/hex.c b/win/src/stm32flash_serial/src/parsers/hex.c deleted file mode 100644 index 3baf85623..000000000 --- a/win/src/stm32flash_serial/src/parsers/hex.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#include -#include -#include -#include -#include -#include -#include - -#include "hex.h" -#include "../utils.h" - -typedef struct { - size_t data_len, offset; - uint8_t *data; - uint8_t base; -} hex_t; - -void* hex_init() { - return calloc(sizeof(hex_t), 1); -} - -parser_err_t hex_open(void *storage, const char *filename, const char write) { - hex_t *st = storage; - if (write) { - return PARSER_ERR_RDONLY; - } else { - char mark; - int i, fd; - uint8_t checksum; - unsigned int c; - uint32_t base = 0; - unsigned int last_address = 0x0; - - fd = open(filename, O_RDONLY); - if (fd < 0) - return PARSER_ERR_SYSTEM; - - /* read in the file */ - - while(read(fd, &mark, 1) != 0) { - if (mark == '\n' || mark == '\r') continue; - if (mark != ':') - return PARSER_ERR_INVALID_FILE; - - char buffer[9]; - unsigned int reclen, address, type; - uint8_t *record = NULL; - - /* get the reclen, address, and type */ - buffer[8] = 0; - if (read(fd, &buffer, 8) != 8) return PARSER_ERR_INVALID_FILE; - if (sscanf(buffer, "%2x%4x%2x", &reclen, &address, &type) != 3) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* setup the checksum */ - checksum = - reclen + - ((address & 0xFF00) >> 8) + - ((address & 0x00FF) >> 0) + - type; - - switch(type) { - /* data record */ - case 0: - c = address - last_address; - st->data = realloc(st->data, st->data_len + c + reclen); - - /* if there is a gap, set it to 0xff and increment the length */ - if (c > 0) { - memset(&st->data[st->data_len], 0xff, c); - st->data_len += c; - } - - last_address = address + reclen; - record = &st->data[st->data_len]; - st->data_len += reclen; - break; - - /* extended segment address record */ - case 2: - base = 0; - break; - - /* extended linear address record */ - case 4: - base = address; - break; - } - - buffer[2] = 0; - for(i = 0; i < reclen; ++i) { - if (read(fd, &buffer, 2) != 2 || sscanf(buffer, "%2x", &c) != 1) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* add the byte to the checksum */ - checksum += c; - - switch(type) { - case 0: - if (record != NULL) { - record[i] = c; - } else { - return PARSER_ERR_INVALID_FILE; - } - break; - - case 2: - case 4: - base = (base << 8) | c; - break; - } - } - - /* read, scan, and verify the checksum */ - if ( - read(fd, &buffer, 2 ) != 2 || - sscanf(buffer, "%2x", &c) != 1 || - (uint8_t)(checksum + c) != 0x00 - ) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - switch(type) { - /* EOF */ - case 1: - close(fd); - return PARSER_ERR_OK; - - /* address record */ - case 2: base = base << 4; - case 4: base = be_u32(base); - /* Reset last_address since our base changed */ - last_address = 0; - - if (st->base == 0) { - st->base = base; - break; - } - - /* we cant cope with files out of order */ - if (base < st->base) { - close(fd); - return PARSER_ERR_INVALID_FILE; - } - - /* if there is a gap, enlarge and fill with zeros */ - unsigned int len = base - st->base; - if (len > st->data_len) { - st->data = realloc(st->data, len); - memset(&st->data[st->data_len], 0, len - st->data_len); - st->data_len = len; - } - break; - } - } - - close(fd); - return PARSER_ERR_OK; - } -} - -parser_err_t hex_close(void *storage) { - hex_t *st = storage; - if (st) free(st->data); - free(st); - return PARSER_ERR_OK; -} - -unsigned int hex_size(void *storage) { - hex_t *st = storage; - return st->data_len; -} - -parser_err_t hex_read(void *storage, void *data, unsigned int *len) { - hex_t *st = storage; - unsigned int left = st->data_len - st->offset; - unsigned int get = left > *len ? *len : left; - - memcpy(data, &st->data[st->offset], get); - st->offset += get; - - *len = get; - return PARSER_ERR_OK; -} - -parser_err_t hex_write(void *storage, void *data, unsigned int len) { - return PARSER_ERR_RDONLY; -} - -parser_t PARSER_HEX = { - "Intel HEX", - hex_init, - hex_open, - hex_close, - hex_size, - hex_read, - hex_write -}; - diff --git a/win/src/stm32flash_serial/src/parsers/hex.h b/win/src/stm32flash_serial/src/parsers/hex.h deleted file mode 100644 index 02413c9c9..000000000 --- a/win/src/stm32flash_serial/src/parsers/hex.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _PARSER_HEX_H -#define _PARSER_HEX_H - -#include "parser.h" - -extern parser_t PARSER_HEX; -#endif diff --git a/win/src/stm32flash_serial/src/parsers/parser.h b/win/src/stm32flash_serial/src/parsers/parser.h deleted file mode 100644 index c2fae3cf8..000000000 --- a/win/src/stm32flash_serial/src/parsers/parser.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_PARSER -#define _H_PARSER - -enum parser_err { - PARSER_ERR_OK, - PARSER_ERR_SYSTEM, - PARSER_ERR_INVALID_FILE, - PARSER_ERR_WRONLY, - PARSER_ERR_RDONLY -}; -typedef enum parser_err parser_err_t; - -struct parser { - const char *name; - void* (*init )(); /* initialise the parser */ - parser_err_t (*open )(void *storage, const char *filename, const char write); /* open the file for read|write */ - parser_err_t (*close)(void *storage); /* close and free the parser */ - unsigned int (*size )(void *storage); /* get the total data size */ - parser_err_t (*read )(void *storage, void *data, unsigned int *len); /* read a block of data */ - parser_err_t (*write)(void *storage, void *data, unsigned int len); /* write a block of data */ -}; -typedef struct parser parser_t; - -static inline const char* parser_errstr(parser_err_t err) { - switch(err) { - case PARSER_ERR_OK : return "OK"; - case PARSER_ERR_SYSTEM : return "System Error"; - case PARSER_ERR_INVALID_FILE: return "Invalid File"; - case PARSER_ERR_WRONLY : return "Parser can only write"; - case PARSER_ERR_RDONLY : return "Parser can only read"; - default: - return "Unknown Error"; - } -} - -#endif diff --git a/win/src/stm32flash_serial/src/port.c b/win/src/stm32flash_serial/src/port.c deleted file mode 100644 index 08e58cc34..000000000 --- a/win/src/stm32flash_serial/src/port.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include - -#include "serial.h" -#include "port.h" - - -extern struct port_interface port_serial; -extern struct port_interface port_i2c; - -static struct port_interface *ports[] = { - &port_serial, - &port_i2c, - NULL, -}; - - -port_err_t port_open(struct port_options *ops, struct port_interface **outport) -{ - int ret; - static struct port_interface **port; - - for (port = ports; *port; port++) { - ret = (*port)->open(*port, ops); - if (ret == PORT_ERR_NODEV) - continue; - if (ret == PORT_ERR_OK) - break; - fprintf(stderr, "Error probing interface \"%s\"\n", - (*port)->name); - } - if (*port == NULL) { - fprintf(stderr, "Cannot handle device \"%s\"\n", - ops->device); - return PORT_ERR_UNKNOWN; - } - - *outport = *port; - return PORT_ERR_OK; -} diff --git a/win/src/stm32flash_serial/src/port.h b/win/src/stm32flash_serial/src/port.h deleted file mode 100644 index 290f03496..000000000 --- a/win/src/stm32flash_serial/src/port.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2014 Antonio Borneo - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_PORT -#define _H_PORT - -typedef enum { - PORT_ERR_OK = 0, - PORT_ERR_NODEV, /* No such device */ - PORT_ERR_TIMEDOUT, /* Operation timed out */ - PORT_ERR_UNKNOWN, -} port_err_t; - -/* flags */ -#define PORT_BYTE (1 << 0) /* byte (not frame) oriented */ -#define PORT_GVR_ETX (1 << 1) /* cmd GVR returns protection status */ -#define PORT_CMD_INIT (1 << 2) /* use INIT cmd to autodetect speed */ -#define PORT_RETRY (1 << 3) /* allowed read() retry after timeout */ -#define PORT_STRETCH_W (1 << 4) /* warning for no-stretching commands */ - -/* all options and flags used to open and configure an interface */ -struct port_options { - const char *device; - serial_baud_t baudRate; - const char *serial_mode; - int bus_addr; - int rx_frame_max; - int tx_frame_max; -}; - -/* - * Specify the length of reply for command GET - * This is helpful for frame-oriented protocols, e.g. i2c, to avoid time - * consuming try-fail-timeout-retry operation. - * On byte-oriented protocols, i.e. UART, this information would be skipped - * after read the first byte, so not needed. - */ -struct varlen_cmd { - uint8_t version; - uint8_t length; -}; - -struct port_interface { - const char *name; - unsigned flags; - port_err_t (*open)(struct port_interface *port, struct port_options *ops); - port_err_t (*close)(struct port_interface *port); - port_err_t (*read)(struct port_interface *port, void *buf, size_t nbyte); - port_err_t (*write)(struct port_interface *port, void *buf, size_t nbyte); - port_err_t (*gpio)(struct port_interface *port, serial_gpio_t n, int level); - const char *(*get_cfg_str)(struct port_interface *port); - struct varlen_cmd *cmd_get_reply; - void *private; -}; - -port_err_t port_open(struct port_options *ops, struct port_interface **outport); - -#endif diff --git a/win/src/stm32flash_serial/src/protocol.txt b/win/src/stm32flash_serial/src/protocol.txt deleted file mode 100644 index 039109908..000000000 --- a/win/src/stm32flash_serial/src/protocol.txt +++ /dev/null @@ -1,19 +0,0 @@ -The communication protocol used by ST bootloader is documented in following ST -application notes, depending on communication port. - -In current version of stm32flash are supported only UART and I2C ports. - -* AN3154: CAN protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/CD00264321.pdf - -* AN3155: USART protocol used in the STM32(TM) bootloader - http://www.st.com/web/en/resource/technical/document/application_note/CD00264342.pdf - -* AN4221: I2C protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/DM00072315.pdf - -* AN4286: SPI protocol used in the STM32 bootloader - http://www.st.com/web/en/resource/technical/document/application_note/DM00081379.pdf - -Boot mode selection for STM32 is documented in ST application note AN2606, available in ST website: - http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf diff --git a/win/src/stm32flash_serial/src/serial.h b/win/src/stm32flash_serial/src/serial.h deleted file mode 100644 index 227ba163b..000000000 --- a/win/src/stm32flash_serial/src/serial.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _SERIAL_H -#define _SERIAL_H - -typedef struct serial serial_t; - -typedef enum { - SERIAL_PARITY_NONE, - SERIAL_PARITY_EVEN, - SERIAL_PARITY_ODD, - - SERIAL_PARITY_INVALID -} serial_parity_t; - -typedef enum { - SERIAL_BITS_5, - SERIAL_BITS_6, - SERIAL_BITS_7, - SERIAL_BITS_8, - - SERIAL_BITS_INVALID -} serial_bits_t; - -typedef enum { - SERIAL_BAUD_1200, - SERIAL_BAUD_1800, - SERIAL_BAUD_2400, - SERIAL_BAUD_4800, - SERIAL_BAUD_9600, - SERIAL_BAUD_19200, - SERIAL_BAUD_38400, - SERIAL_BAUD_57600, - SERIAL_BAUD_115200, - SERIAL_BAUD_128000, - SERIAL_BAUD_230400, - SERIAL_BAUD_256000, - SERIAL_BAUD_460800, - SERIAL_BAUD_500000, - SERIAL_BAUD_576000, - SERIAL_BAUD_921600, - SERIAL_BAUD_1000000, - SERIAL_BAUD_1500000, - SERIAL_BAUD_2000000, - - SERIAL_BAUD_INVALID -} serial_baud_t; - -typedef enum { - SERIAL_STOPBIT_1, - SERIAL_STOPBIT_2, - - SERIAL_STOPBIT_INVALID -} serial_stopbit_t; - -typedef enum { - GPIO_RTS = 1, - GPIO_DTR, - GPIO_BRK, -} serial_gpio_t; - -/* common helper functions */ -serial_baud_t serial_get_baud(const unsigned int baud); -unsigned int serial_get_baud_int(const serial_baud_t baud); -serial_bits_t serial_get_bits(const char *mode); -unsigned int serial_get_bits_int(const serial_bits_t bits); -serial_parity_t serial_get_parity(const char *mode); -char serial_get_parity_str(const serial_parity_t parity); -serial_stopbit_t serial_get_stopbit(const char *mode); -unsigned int serial_get_stopbit_int(const serial_stopbit_t stopbit); - -#endif diff --git a/win/src/stm32flash_serial/src/serial_common.c b/win/src/stm32flash_serial/src/serial_common.c deleted file mode 100644 index 43e48e1ac..000000000 --- a/win/src/stm32flash_serial/src/serial_common.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "serial.h" - -serial_baud_t serial_get_baud(const unsigned int baud) { - switch(baud) { - case 1200: return SERIAL_BAUD_1200 ; - case 1800: return SERIAL_BAUD_1800 ; - case 2400: return SERIAL_BAUD_2400 ; - case 4800: return SERIAL_BAUD_4800 ; - case 9600: return SERIAL_BAUD_9600 ; - case 19200: return SERIAL_BAUD_19200 ; - case 38400: return SERIAL_BAUD_38400 ; - case 57600: return SERIAL_BAUD_57600 ; - case 115200: return SERIAL_BAUD_115200; - case 128000: return SERIAL_BAUD_128000; - case 230400: return SERIAL_BAUD_230400; - case 256000: return SERIAL_BAUD_256000; - case 460800: return SERIAL_BAUD_460800; - case 500000: return SERIAL_BAUD_500000; - case 576000: return SERIAL_BAUD_576000; - case 921600: return SERIAL_BAUD_921600; - case 1000000: return SERIAL_BAUD_1000000; - case 1500000: return SERIAL_BAUD_1500000; - case 2000000: return SERIAL_BAUD_2000000; - - default: - return SERIAL_BAUD_INVALID; - } -} - -unsigned int serial_get_baud_int(const serial_baud_t baud) { - switch(baud) { - case SERIAL_BAUD_1200 : return 1200 ; - case SERIAL_BAUD_1800 : return 1800 ; - case SERIAL_BAUD_2400 : return 2400 ; - case SERIAL_BAUD_4800 : return 4800 ; - case SERIAL_BAUD_9600 : return 9600 ; - case SERIAL_BAUD_19200 : return 19200 ; - case SERIAL_BAUD_38400 : return 38400 ; - case SERIAL_BAUD_57600 : return 57600 ; - case SERIAL_BAUD_115200: return 115200; - case SERIAL_BAUD_128000: return 128000; - case SERIAL_BAUD_230400: return 230400; - case SERIAL_BAUD_256000: return 256000; - case SERIAL_BAUD_460800: return 460800; - case SERIAL_BAUD_500000: return 500000; - case SERIAL_BAUD_576000: return 576000; - case SERIAL_BAUD_921600: return 921600; - case SERIAL_BAUD_1000000: return 1000000; - case SERIAL_BAUD_1500000: return 1500000; - case SERIAL_BAUD_2000000: return 2000000; - - case SERIAL_BAUD_INVALID: - default: - return 0; - } -} - -serial_bits_t serial_get_bits(const char *mode) { - if (!mode) - return SERIAL_BITS_INVALID; - switch(mode[0]) { - case '5': return SERIAL_BITS_5; - case '6': return SERIAL_BITS_6; - case '7': return SERIAL_BITS_7; - case '8': return SERIAL_BITS_8; - - default: - return SERIAL_BITS_INVALID; - } -} - -unsigned int serial_get_bits_int(const serial_bits_t bits) { - switch(bits) { - case SERIAL_BITS_5: return 5; - case SERIAL_BITS_6: return 6; - case SERIAL_BITS_7: return 7; - case SERIAL_BITS_8: return 8; - - default: - return 0; - } -} - -serial_parity_t serial_get_parity(const char *mode) { - if (!mode || !mode[0]) - return SERIAL_PARITY_INVALID; - switch(mode[1]) { - case 'N': - case 'n': - return SERIAL_PARITY_NONE; - case 'E': - case 'e': - return SERIAL_PARITY_EVEN; - case 'O': - case 'o': - return SERIAL_PARITY_ODD; - - default: - return SERIAL_PARITY_INVALID; - } -} - -char serial_get_parity_str(const serial_parity_t parity) { - switch(parity) { - case SERIAL_PARITY_NONE: return 'N'; - case SERIAL_PARITY_EVEN: return 'E'; - case SERIAL_PARITY_ODD : return 'O'; - - default: - return ' '; - } -} - -serial_stopbit_t serial_get_stopbit(const char *mode) { - if (!mode || !mode[0] || !mode[1]) - return SERIAL_STOPBIT_INVALID; - switch(mode[2]) { - case '1': return SERIAL_STOPBIT_1; - case '2': return SERIAL_STOPBIT_2; - - default: - return SERIAL_STOPBIT_INVALID; - } -} - -unsigned int serial_get_stopbit_int(const serial_stopbit_t stopbit) { - switch(stopbit) { - case SERIAL_STOPBIT_1: return 1; - case SERIAL_STOPBIT_2: return 2; - - default: - return 0; - } -} - diff --git a/win/src/stm32flash_serial/src/serial_platform.c b/win/src/stm32flash_serial/src/serial_platform.c deleted file mode 100644 index 98e256921..000000000 --- a/win/src/stm32flash_serial/src/serial_platform.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined(__WIN32__) || defined(__CYGWIN__) -# include "serial_w32.c" -#else -# include "serial_posix.c" -#endif diff --git a/win/src/stm32flash_serial/src/serial_posix.c b/win/src/stm32flash_serial/src/serial_posix.c deleted file mode 100644 index 284b35b20..000000000 --- a/win/src/stm32flash_serial/src/serial_posix.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - -struct serial { - int fd; - struct termios oldtio; - struct termios newtio; - char setup_str[11]; -}; - -static serial_t *serial_open(const char *device) -{ - serial_t *h = calloc(sizeof(serial_t), 1); - - h->fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); - if (h->fd < 0) { - free(h); - return NULL; - } - fcntl(h->fd, F_SETFL, 0); - - tcgetattr(h->fd, &h->oldtio); - tcgetattr(h->fd, &h->newtio); - - return h; -} - -static void serial_flush(const serial_t *h) -{ - tcflush(h->fd, TCIFLUSH); -} - -static void serial_close(serial_t *h) -{ - serial_flush(h); - tcsetattr(h->fd, TCSANOW, &h->oldtio); - close(h->fd); - free(h); -} - -static port_err_t serial_setup(serial_t *h, const serial_baud_t baud, - const serial_bits_t bits, - const serial_parity_t parity, - const serial_stopbit_t stopbit) -{ - speed_t port_baud; - tcflag_t port_bits; - tcflag_t port_parity; - tcflag_t port_stop; - struct termios settings; - - switch (baud) { - case SERIAL_BAUD_1200: port_baud = B1200; break; - case SERIAL_BAUD_1800: port_baud = B1800; break; - case SERIAL_BAUD_2400: port_baud = B2400; break; - case SERIAL_BAUD_4800: port_baud = B4800; break; - case SERIAL_BAUD_9600: port_baud = B9600; break; - case SERIAL_BAUD_19200: port_baud = B19200; break; - case SERIAL_BAUD_38400: port_baud = B38400; break; - case SERIAL_BAUD_57600: port_baud = B57600; break; - case SERIAL_BAUD_115200: port_baud = B115200; break; - case SERIAL_BAUD_230400: port_baud = B230400; break; -#ifdef B460800 - case SERIAL_BAUD_460800: port_baud = B460800; break; -#endif /* B460800 */ -#ifdef B921600 - case SERIAL_BAUD_921600: port_baud = B921600; break; -#endif /* B921600 */ -#ifdef B500000 - case SERIAL_BAUD_500000: port_baud = B500000; break; -#endif /* B500000 */ -#ifdef B576000 - case SERIAL_BAUD_576000: port_baud = B576000; break; -#endif /* B576000 */ -#ifdef B1000000 - case SERIAL_BAUD_1000000: port_baud = B1000000; break; -#endif /* B1000000 */ -#ifdef B1500000 - case SERIAL_BAUD_1500000: port_baud = B1500000; break; -#endif /* B1500000 */ -#ifdef B2000000 - case SERIAL_BAUD_2000000: port_baud = B2000000; break; -#endif /* B2000000 */ - - case SERIAL_BAUD_INVALID: - default: - return PORT_ERR_UNKNOWN; - } - - switch (bits) { - case SERIAL_BITS_5: port_bits = CS5; break; - case SERIAL_BITS_6: port_bits = CS6; break; - case SERIAL_BITS_7: port_bits = CS7; break; - case SERIAL_BITS_8: port_bits = CS8; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (parity) { - case SERIAL_PARITY_NONE: port_parity = 0; break; - case SERIAL_PARITY_EVEN: port_parity = PARENB; break; - case SERIAL_PARITY_ODD: port_parity = PARENB | PARODD; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (stopbit) { - case SERIAL_STOPBIT_1: port_stop = 0; break; - case SERIAL_STOPBIT_2: port_stop = CSTOPB; break; - - default: - return PORT_ERR_UNKNOWN; - } - - /* reset the settings */ -#ifndef __sun /* Used by GNU and BSD. Ignore __SVR4 in test. */ - cfmakeraw(&h->newtio); -#else /* __sun */ - h->newtio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR - | IGNCR | ICRNL | IXON); - if (port_parity) - h->newtio.c_iflag |= INPCK; - - h->newtio.c_oflag &= ~OPOST; - h->newtio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - h->newtio.c_cflag &= ~(CSIZE | PARENB); - h->newtio.c_cflag |= CS8; -#endif /* __sun */ -#ifdef __QNXNTO__ - h->newtio.c_cflag &= ~(CSIZE | IHFLOW | OHFLOW); -#else - h->newtio.c_cflag &= ~(CSIZE | CRTSCTS); -#endif - h->newtio.c_cflag &= ~(CSIZE | CRTSCTS); - h->newtio.c_iflag &= ~(IXON | IXOFF | IXANY | IGNPAR); - h->newtio.c_lflag &= ~(ECHOK | ECHOCTL | ECHOKE); - h->newtio.c_oflag &= ~(OPOST | ONLCR); - - /* setup the new settings */ - cfsetispeed(&h->newtio, port_baud); - cfsetospeed(&h->newtio, port_baud); - h->newtio.c_cflag |= - port_parity | - port_bits | - port_stop | - CLOCAL | - CREAD; - - h->newtio.c_cc[VMIN] = 0; - h->newtio.c_cc[VTIME] = 5; /* in units of 0.1 s */ - - /* set the settings */ - serial_flush(h); - if (tcsetattr(h->fd, TCSANOW, &h->newtio) != 0) - return PORT_ERR_UNKNOWN; - -/* this check fails on CDC-ACM devices, bits 16 and 17 of cflag differ! - * it has been disabled below for now -jcw, 2015-11-09 - if (settings.c_cflag != h->newtio.c_cflag) - fprintf(stderr, "c_cflag mismatch %lx\n", - settings.c_cflag ^ h->newtio.c_cflag); - */ - - /* confirm they were set */ - tcgetattr(h->fd, &settings); - if (settings.c_iflag != h->newtio.c_iflag || - settings.c_oflag != h->newtio.c_oflag || - //settings.c_cflag != h->newtio.c_cflag || - settings.c_lflag != h->newtio.c_lflag) - return PORT_ERR_UNKNOWN; - - snprintf(h->setup_str, sizeof(h->setup_str), "%u %d%c%d", - serial_get_baud_int(baud), - serial_get_bits_int(bits), - serial_get_parity_str(parity), - serial_get_stopbit_int(stopbit)); - return PORT_ERR_OK; -} - -/* - * Roger clark. - * This function is no longer used. But has just been commented out in case it needs - * to be reinstated in the future - -static int startswith(const char *haystack, const char *needle) { - return strncmp(haystack, needle, strlen(needle)) == 0; -} -*/ - -static int is_tty(const char *path) { - char resolved[PATH_MAX]; - - if(!realpath(path, resolved)) return 0; - - - /* - * Roger Clark - * Commented out this check, because on OSX some devices are /dev/cu - * and some users use symbolic links to devices, hence the name may not even start - * with /dev - - if(startswith(resolved, "/dev/tty")) return 1; - - return 0; - */ - - return 1; -} - -static port_err_t serial_posix_open(struct port_interface *port, - struct port_options *ops) -{ - serial_t *h; - - /* 1. check device name match */ - if (!is_tty(ops->device)) - return PORT_ERR_NODEV; - - /* 2. check options */ - if (ops->baudRate == SERIAL_BAUD_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_parity(ops->serial_mode) == SERIAL_PARITY_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) - return PORT_ERR_UNKNOWN; - - /* 3. open it */ - h = serial_open(ops->device); - if (h == NULL) - return PORT_ERR_UNKNOWN; - - /* 4. set options */ - if (serial_setup(h, ops->baudRate, - serial_get_bits(ops->serial_mode), - serial_get_parity(ops->serial_mode), - serial_get_stopbit(ops->serial_mode) - ) != PORT_ERR_OK) { - serial_close(h); - return PORT_ERR_UNKNOWN; - } - - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t serial_posix_close(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - serial_close(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t serial_posix_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - ssize_t r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - r = read(h->fd, pos, nbyte); - if (r == 0) - return PORT_ERR_TIMEDOUT; - if (r < 0) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_posix_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - ssize_t r; - const uint8_t *pos = (const uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - r = write(h->fd, pos, nbyte); - if (r < 1) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_posix_gpio(struct port_interface *port, - serial_gpio_t n, int level) -{ - serial_t *h; - int bit, lines; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - switch (n) { - case GPIO_RTS: - bit = TIOCM_RTS; - break; - - case GPIO_DTR: - bit = TIOCM_DTR; - break; - - case GPIO_BRK: - if (level == 0) - return PORT_ERR_OK; - if (tcsendbreak(h->fd, 1)) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; - - default: - return PORT_ERR_UNKNOWN; - } - - /* handle RTS/DTR */ - if (ioctl(h->fd, TIOCMGET, &lines)) - return PORT_ERR_UNKNOWN; - lines = level ? lines | bit : lines & ~bit; - if (ioctl(h->fd, TIOCMSET, &lines)) - return PORT_ERR_UNKNOWN; - - return PORT_ERR_OK; -} - -static const char *serial_posix_get_cfg_str(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - return h ? h->setup_str : "INVALID"; -} - -struct port_interface port_serial = { - .name = "serial_posix", - .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, - .open = serial_posix_open, - .close = serial_posix_close, - .read = serial_posix_read, - .write = serial_posix_write, - .gpio = serial_posix_gpio, - .get_cfg_str = serial_posix_get_cfg_str, -}; diff --git a/win/src/stm32flash_serial/src/serial_w32.c b/win/src/stm32flash_serial/src/serial_w32.c deleted file mode 100644 index 56772c0a0..000000000 --- a/win/src/stm32flash_serial/src/serial_w32.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2010 Gareth McMullin - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - -struct serial { - HANDLE fd; - DCB oldtio; - DCB newtio; - char setup_str[11]; -}; - -static serial_t *serial_open(const char *device) -{ - serial_t *h = calloc(sizeof(serial_t), 1); - char *devName; - - /* timeout in ms */ - COMMTIMEOUTS timeouts = {MAXDWORD, MAXDWORD, 500, 0, 0}; - - /* Fix the device name if required */ - if (strlen(device) > 4 && device[0] != '\\') { - devName = calloc(1, strlen(device) + 5); - sprintf(devName, "\\\\.\\%s", device); - } else { - devName = (char *)device; - } - - /* Create file handle for port */ - h->fd = CreateFile(devName, GENERIC_READ | GENERIC_WRITE, - 0, /* Exclusive access */ - NULL, /* No security */ - OPEN_EXISTING, - 0, /* No overlap */ - NULL); - - if (devName != device) - free(devName); - - if (h->fd == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_FILE_NOT_FOUND) - fprintf(stderr, "File not found: %s\n", device); - return NULL; - } - - SetupComm(h->fd, 4096, 4096); /* Set input and output buffer size */ - - SetCommTimeouts(h->fd, &timeouts); - - SetCommMask(h->fd, EV_ERR); /* Notify us of error events */ - - GetCommState(h->fd, &h->oldtio); /* Retrieve port parameters */ - GetCommState(h->fd, &h->newtio); /* Retrieve port parameters */ - - /* PurgeComm(h->fd, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); */ - - return h; -} - -static void serial_flush(const serial_t *h) -{ - /* We shouldn't need to flush in non-overlapping (blocking) mode */ - /* tcflush(h->fd, TCIFLUSH); */ -} - -static void serial_close(serial_t *h) -{ - serial_flush(h); - SetCommState(h->fd, &h->oldtio); - CloseHandle(h->fd); - free(h); -} - -static port_err_t serial_setup(serial_t *h, - const serial_baud_t baud, - const serial_bits_t bits, - const serial_parity_t parity, - const serial_stopbit_t stopbit) -{ - switch (baud) { - case SERIAL_BAUD_1200: h->newtio.BaudRate = CBR_1200; break; - /* case SERIAL_BAUD_1800: h->newtio.BaudRate = CBR_1800; break; */ - case SERIAL_BAUD_2400: h->newtio.BaudRate = CBR_2400; break; - case SERIAL_BAUD_4800: h->newtio.BaudRate = CBR_4800; break; - case SERIAL_BAUD_9600: h->newtio.BaudRate = CBR_9600; break; - case SERIAL_BAUD_19200: h->newtio.BaudRate = CBR_19200; break; - case SERIAL_BAUD_38400: h->newtio.BaudRate = CBR_38400; break; - case SERIAL_BAUD_57600: h->newtio.BaudRate = CBR_57600; break; - case SERIAL_BAUD_115200: h->newtio.BaudRate = CBR_115200; break; - case SERIAL_BAUD_128000: h->newtio.BaudRate = CBR_128000; break; - case SERIAL_BAUD_256000: h->newtio.BaudRate = CBR_256000; break; - /* These are not defined in WinBase.h and might work or not */ - case SERIAL_BAUD_230400: h->newtio.BaudRate = 230400; break; - case SERIAL_BAUD_460800: h->newtio.BaudRate = 460800; break; - case SERIAL_BAUD_500000: h->newtio.BaudRate = 500000; break; - case SERIAL_BAUD_576000: h->newtio.BaudRate = 576000; break; - case SERIAL_BAUD_921600: h->newtio.BaudRate = 921600; break; - case SERIAL_BAUD_1000000: h->newtio.BaudRate = 1000000; break; - case SERIAL_BAUD_1500000: h->newtio.BaudRate = 1500000; break; - case SERIAL_BAUD_2000000: h->newtio.BaudRate = 2000000; break; - case SERIAL_BAUD_INVALID: - - default: - return PORT_ERR_UNKNOWN; - } - - switch (bits) { - case SERIAL_BITS_5: h->newtio.ByteSize = 5; break; - case SERIAL_BITS_6: h->newtio.ByteSize = 6; break; - case SERIAL_BITS_7: h->newtio.ByteSize = 7; break; - case SERIAL_BITS_8: h->newtio.ByteSize = 8; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (parity) { - case SERIAL_PARITY_NONE: h->newtio.Parity = NOPARITY; break; - case SERIAL_PARITY_EVEN: h->newtio.Parity = EVENPARITY; break; - case SERIAL_PARITY_ODD: h->newtio.Parity = ODDPARITY; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (stopbit) { - case SERIAL_STOPBIT_1: h->newtio.StopBits = ONESTOPBIT; break; - case SERIAL_STOPBIT_2: h->newtio.StopBits = TWOSTOPBITS; break; - - default: - return PORT_ERR_UNKNOWN; - } - - /* reset the settings */ - h->newtio.fOutxCtsFlow = FALSE; - h->newtio.fOutxDsrFlow = FALSE; - h->newtio.fOutX = FALSE; - h->newtio.fInX = FALSE; - h->newtio.fNull = 0; - h->newtio.fAbortOnError = 0; - - /* set the settings */ - serial_flush(h); - if (!SetCommState(h->fd, &h->newtio)) - return PORT_ERR_UNKNOWN; - - snprintf(h->setup_str, sizeof(h->setup_str), "%u %d%c%d", - serial_get_baud_int(baud), - serial_get_bits_int(bits), - serial_get_parity_str(parity), - serial_get_stopbit_int(stopbit) - ); - return PORT_ERR_OK; -} - -static port_err_t serial_w32_open(struct port_interface *port, - struct port_options *ops) -{ - serial_t *h; - - /* 1. check device name match */ - if (!((strlen(ops->device) == 4 || strlen(ops->device) == 5) - && !strncmp(ops->device, "COM", 3) && isdigit(ops->device[3])) - && !(!strncmp(ops->device, "\\\\.\\COM", strlen("\\\\.\\COM")) - && isdigit(ops->device[strlen("\\\\.\\COM")]))) - return PORT_ERR_NODEV; - - /* 2. check options */ - if (ops->baudRate == SERIAL_BAUD_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_parity(ops->serial_mode) == SERIAL_PARITY_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) - return PORT_ERR_UNKNOWN; - - /* 3. open it */ - h = serial_open(ops->device); - if (h == NULL) - return PORT_ERR_UNKNOWN; - - /* 4. set options */ - if (serial_setup(h, ops->baudRate, - serial_get_bits(ops->serial_mode), - serial_get_parity(ops->serial_mode), - serial_get_stopbit(ops->serial_mode) - ) != PORT_ERR_OK) { - serial_close(h); - return PORT_ERR_UNKNOWN; - } - - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t serial_w32_close(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - serial_close(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t serial_w32_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - DWORD r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - ReadFile(h->fd, pos, nbyte, &r, NULL); - if (r == 0) - return PORT_ERR_TIMEDOUT; - if (r < 0) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_w32_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - DWORD r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - if (!WriteFile(h->fd, pos, nbyte, &r, NULL)) - return PORT_ERR_UNKNOWN; - if (r < 1) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_w32_gpio(struct port_interface *port, - serial_gpio_t n, int level) -{ - serial_t *h; - int bit; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - switch (n) { - case GPIO_RTS: - bit = level ? SETRTS : CLRRTS; - break; - - case GPIO_DTR: - bit = level ? SETDTR : CLRDTR; - break; - - case GPIO_BRK: - if (level == 0) - return PORT_ERR_OK; - if (EscapeCommFunction(h->fd, SETBREAK) == 0) - return PORT_ERR_UNKNOWN; - usleep(500000); - if (EscapeCommFunction(h->fd, CLRBREAK) == 0) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; - - default: - return PORT_ERR_UNKNOWN; - } - - /* handle RTS/DTR */ - if (EscapeCommFunction(h->fd, bit) == 0) - return PORT_ERR_UNKNOWN; - - return PORT_ERR_OK; -} - -static const char *serial_w32_get_cfg_str(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - return h ? h->setup_str : "INVALID"; -} - -struct port_interface port_serial = { - .name = "serial_w32", - .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, - .open = serial_w32_open, - .close = serial_w32_close, - .read = serial_w32_read, - .write = serial_w32_write, - .gpio = serial_w32_gpio, - .get_cfg_str = serial_w32_get_cfg_str, -}; diff --git a/win/src/stm32flash_serial/src/stm32.c b/win/src/stm32flash_serial/src/stm32.c deleted file mode 100644 index 74047d244..000000000 --- a/win/src/stm32flash_serial/src/stm32.c +++ /dev/null @@ -1,1048 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright 2010 Geoffrey McRae - Copyright 2012-2014 Tormod Volden - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include - -#include "stm32.h" -#include "port.h" -#include "utils.h" - -#define STM32_ACK 0x79 -#define STM32_NACK 0x1F -#define STM32_BUSY 0x76 - -#define STM32_CMD_INIT 0x7F -#define STM32_CMD_GET 0x00 /* get the version and command supported */ -#define STM32_CMD_GVR 0x01 /* get version and read protection status */ -#define STM32_CMD_GID 0x02 /* get ID */ -#define STM32_CMD_RM 0x11 /* read memory */ -#define STM32_CMD_GO 0x21 /* go */ -#define STM32_CMD_WM 0x31 /* write memory */ -#define STM32_CMD_WM_NS 0x32 /* no-stretch write memory */ -#define STM32_CMD_ER 0x43 /* erase */ -#define STM32_CMD_EE 0x44 /* extended erase */ -#define STM32_CMD_EE_NS 0x45 /* extended erase no-stretch */ -#define STM32_CMD_WP 0x63 /* write protect */ -#define STM32_CMD_WP_NS 0x64 /* write protect no-stretch */ -#define STM32_CMD_UW 0x73 /* write unprotect */ -#define STM32_CMD_UW_NS 0x74 /* write unprotect no-stretch */ -#define STM32_CMD_RP 0x82 /* readout protect */ -#define STM32_CMD_RP_NS 0x83 /* readout protect no-stretch */ -#define STM32_CMD_UR 0x92 /* readout unprotect */ -#define STM32_CMD_UR_NS 0x93 /* readout unprotect no-stretch */ -#define STM32_CMD_CRC 0xA1 /* compute CRC */ -#define STM32_CMD_ERR 0xFF /* not a valid command */ - -#define STM32_RESYNC_TIMEOUT 35 /* seconds */ -#define STM32_MASSERASE_TIMEOUT 35 /* seconds */ -#define STM32_SECTERASE_TIMEOUT 5 /* seconds */ -#define STM32_BLKWRITE_TIMEOUT 1 /* seconds */ -#define STM32_WUNPROT_TIMEOUT 1 /* seconds */ -#define STM32_WPROT_TIMEOUT 1 /* seconds */ -#define STM32_RPROT_TIMEOUT 1 /* seconds */ - -#define STM32_CMD_GET_LENGTH 17 /* bytes in the reply */ - -struct stm32_cmd { - uint8_t get; - uint8_t gvr; - uint8_t gid; - uint8_t rm; - uint8_t go; - uint8_t wm; - uint8_t er; /* this may be extended erase */ - uint8_t wp; - uint8_t uw; - uint8_t rp; - uint8_t ur; - uint8_t crc; -}; - -/* Reset code for ARMv7-M (Cortex-M3) and ARMv6-M (Cortex-M0) - * see ARMv7-M or ARMv6-M Architecture Reference Manual (table B3-8) - * or "The definitive guide to the ARM Cortex-M3", section 14.4. - */ -static const uint8_t stm_reset_code[] = { - 0x01, 0x49, // ldr r1, [pc, #4] ; () - 0x02, 0x4A, // ldr r2, [pc, #8] ; () - 0x0A, 0x60, // str r2, [r1, #0] - 0xfe, 0xe7, // endless: b endless - 0x0c, 0xed, 0x00, 0xe0, // .word 0xe000ed0c = NVIC AIRCR register address - 0x04, 0x00, 0xfa, 0x05 // .word 0x05fa0004 = VECTKEY | SYSRESETREQ -}; - -static const uint32_t stm_reset_code_length = sizeof(stm_reset_code); - -extern const stm32_dev_t devices[]; - -static void stm32_warn_stretching(const char *f) -{ - fprintf(stderr, "Attention !!!\n"); - fprintf(stderr, "\tThis %s error could be caused by your I2C\n", f); - fprintf(stderr, "\tcontroller not accepting \"clock stretching\"\n"); - fprintf(stderr, "\tas required by bootloader.\n"); - fprintf(stderr, "\tCheck \"I2C.txt\" in stm32flash source code.\n"); -} - -static stm32_err_t stm32_get_ack_timeout(const stm32_t *stm, time_t timeout) -{ - struct port_interface *port = stm->port; - uint8_t byte; - port_err_t p_err; - time_t t0, t1; - - if (!(port->flags & PORT_RETRY)) - timeout = 0; - - if (timeout) - time(&t0); - - do { - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_TIMEDOUT && timeout) { - time(&t1); - if (t1 < t0 + timeout) - continue; - } - - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to read ACK byte\n"); - return STM32_ERR_UNKNOWN; - } - - if (byte == STM32_ACK) - return STM32_ERR_OK; - if (byte == STM32_NACK) - return STM32_ERR_NACK; - if (byte != STM32_BUSY) { - fprintf(stderr, "Got byte 0x%02x instead of ACK\n", - byte); - return STM32_ERR_UNKNOWN; - } - } while (1); -} - -static stm32_err_t stm32_get_ack(const stm32_t *stm) -{ - return stm32_get_ack_timeout(stm, 0); -} - -static stm32_err_t stm32_send_command_timeout(const stm32_t *stm, - const uint8_t cmd, - time_t timeout) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - port_err_t p_err; - uint8_t buf[2]; - - buf[0] = cmd; - buf[1] = cmd ^ 0xFF; - p_err = port->write(port, buf, 2); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send command\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, timeout); - if (s_err == STM32_ERR_OK) - return STM32_ERR_OK; - if (s_err == STM32_ERR_NACK) - fprintf(stderr, "Got NACK from device on command 0x%02x\n", cmd); - else - fprintf(stderr, "Unexpected reply from device on command 0x%02x\n", cmd); - return STM32_ERR_UNKNOWN; -} - -static stm32_err_t stm32_send_command(const stm32_t *stm, const uint8_t cmd) -{ - return stm32_send_command_timeout(stm, cmd, 0); -} - -/* if we have lost sync, send a wrong command and expect a NACK */ -static stm32_err_t stm32_resync(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - uint8_t buf[2], ack; - time_t t0, t1; - - time(&t0); - t1 = t0; - - buf[0] = STM32_CMD_ERR; - buf[1] = STM32_CMD_ERR ^ 0xFF; - while (t1 < t0 + STM32_RESYNC_TIMEOUT) { - p_err = port->write(port, buf, 2); - if (p_err != PORT_ERR_OK) { - usleep(500000); - time(&t1); - continue; - } - p_err = port->read(port, &ack, 1); - if (p_err != PORT_ERR_OK) { - time(&t1); - continue; - } - if (ack == STM32_NACK) - return STM32_ERR_OK; - time(&t1); - } - return STM32_ERR_UNKNOWN; -} - -/* - * some command receive reply frame with variable length, and length is - * embedded in reply frame itself. - * We can guess the length, but if we guess wrong the protocol gets out - * of sync. - * Use resync for frame oriented interfaces (e.g. I2C) and byte-by-byte - * read for byte oriented interfaces (e.g. UART). - * - * to run safely, data buffer should be allocated for 256+1 bytes - * - * len is value of the first byte in the frame. - */ -static stm32_err_t stm32_guess_len_cmd(const stm32_t *stm, uint8_t cmd, - uint8_t *data, unsigned int len) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - if (port->flags & PORT_BYTE) { - /* interface is UART-like */ - p_err = port->read(port, data, 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - len = data[0]; - p_err = port->read(port, data + 1, len + 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; - } - - p_err = port->read(port, data, len + 2); - if (p_err == PORT_ERR_OK && len == data[0]) - return STM32_ERR_OK; - if (p_err != PORT_ERR_OK) { - /* restart with only one byte */ - if (stm32_resync(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - p_err = port->read(port, data, 1); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - } - - fprintf(stderr, "Re sync (len = %d)\n", data[0]); - if (stm32_resync(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - len = data[0]; - if (stm32_send_command(stm, cmd) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - p_err = port->read(port, data, len + 2); - if (p_err != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; -} - -/* - * Some interface, e.g. UART, requires a specific init sequence to let STM32 - * autodetect the interface speed. - * The sequence is only required one time after reset. - * stm32flash has command line flag "-c" to prevent sending the init sequence - * in case it was already sent before. - * User can easily forget adding "-c". In this case the bootloader would - * interpret the init sequence as part of a command message, then waiting for - * the rest of the message blocking the interface. - * This function sends the init sequence and, in case of timeout, recovers - * the interface. - */ -static stm32_err_t stm32_send_init_seq(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - port_err_t p_err; - uint8_t byte, cmd = STM32_CMD_INIT; - - p_err = port->write(port, &cmd, 1); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send init to device\n"); - return STM32_ERR_UNKNOWN; - } - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_OK && byte == STM32_ACK) - return STM32_ERR_OK; - if (p_err == PORT_ERR_OK && byte == STM32_NACK) { - /* We could get error later, but let's continue, for now. */ - fprintf(stderr, - "Warning: the interface was not closed properly.\n"); - return STM32_ERR_OK; - } - if (p_err != PORT_ERR_TIMEDOUT) { - fprintf(stderr, "Failed to init device.\n"); - return STM32_ERR_UNKNOWN; - } - - /* - * Check if previous STM32_CMD_INIT was taken as first byte - * of a command. Send a new byte, we should get back a NACK. - */ - p_err = port->write(port, &cmd, 1); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Failed to send init to device\n"); - return STM32_ERR_UNKNOWN; - } - p_err = port->read(port, &byte, 1); - if (p_err == PORT_ERR_OK && byte == STM32_NACK) - return STM32_ERR_OK; - fprintf(stderr, "Failed to init device.\n"); - return STM32_ERR_UNKNOWN; -} - -/* find newer command by higher code */ -#define newer(prev, a) (((prev) == STM32_CMD_ERR) \ - ? (a) \ - : (((prev) > (a)) ? (prev) : (a))) - -stm32_t *stm32_init(struct port_interface *port, const char init) -{ - uint8_t len, val, buf[257]; - stm32_t *stm; - int i, new_cmds; - - stm = calloc(sizeof(stm32_t), 1); - stm->cmd = malloc(sizeof(stm32_cmd_t)); - memset(stm->cmd, STM32_CMD_ERR, sizeof(stm32_cmd_t)); - stm->port = port; - - if ((port->flags & PORT_CMD_INIT) && init) - if (stm32_send_init_seq(stm) != STM32_ERR_OK) - return NULL; - - /* get the version and read protection status */ - if (stm32_send_command(stm, STM32_CMD_GVR) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - /* From AN, only UART bootloader returns 3 bytes */ - len = (port->flags & PORT_GVR_ETX) ? 3 : 1; - if (port->read(port, buf, len) != PORT_ERR_OK) - return NULL; - stm->version = buf[0]; - stm->option1 = (port->flags & PORT_GVR_ETX) ? buf[1] : 0; - stm->option2 = (port->flags & PORT_GVR_ETX) ? buf[2] : 0; - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - /* get the bootloader information */ - len = STM32_CMD_GET_LENGTH; - if (port->cmd_get_reply) - for (i = 0; port->cmd_get_reply[i].length; i++) - if (stm->version == port->cmd_get_reply[i].version) { - len = port->cmd_get_reply[i].length; - break; - } - if (stm32_guess_len_cmd(stm, STM32_CMD_GET, buf, len) != STM32_ERR_OK) - return NULL; - len = buf[0] + 1; - stm->bl_version = buf[1]; - new_cmds = 0; - for (i = 1; i < len; i++) { - val = buf[i + 1]; - switch (val) { - case STM32_CMD_GET: - stm->cmd->get = val; break; - case STM32_CMD_GVR: - stm->cmd->gvr = val; break; - case STM32_CMD_GID: - stm->cmd->gid = val; break; - case STM32_CMD_RM: - stm->cmd->rm = val; break; - case STM32_CMD_GO: - stm->cmd->go = val; break; - case STM32_CMD_WM: - case STM32_CMD_WM_NS: - stm->cmd->wm = newer(stm->cmd->wm, val); - break; - case STM32_CMD_ER: - case STM32_CMD_EE: - case STM32_CMD_EE_NS: - stm->cmd->er = newer(stm->cmd->er, val); - break; - case STM32_CMD_WP: - case STM32_CMD_WP_NS: - stm->cmd->wp = newer(stm->cmd->wp, val); - break; - case STM32_CMD_UW: - case STM32_CMD_UW_NS: - stm->cmd->uw = newer(stm->cmd->uw, val); - break; - case STM32_CMD_RP: - case STM32_CMD_RP_NS: - stm->cmd->rp = newer(stm->cmd->rp, val); - break; - case STM32_CMD_UR: - case STM32_CMD_UR_NS: - stm->cmd->ur = newer(stm->cmd->ur, val); - break; - case STM32_CMD_CRC: - stm->cmd->crc = newer(stm->cmd->crc, val); - break; - default: - if (new_cmds++ == 0) - fprintf(stderr, - "GET returns unknown commands (0x%2x", - val); - else - fprintf(stderr, ", 0x%2x", val); - } - } - if (new_cmds) - fprintf(stderr, ")\n"); - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - if (stm->cmd->get == STM32_CMD_ERR - || stm->cmd->gvr == STM32_CMD_ERR - || stm->cmd->gid == STM32_CMD_ERR) { - fprintf(stderr, "Error: bootloader did not returned correct information from GET command\n"); - return NULL; - } - - /* get the device ID */ - if (stm32_guess_len_cmd(stm, stm->cmd->gid, buf, 1) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - len = buf[0] + 1; - if (len < 2) { - stm32_close(stm); - fprintf(stderr, "Only %d bytes sent in the PID, unknown/unsupported device\n", len); - return NULL; - } - stm->pid = (buf[1] << 8) | buf[2]; - if (len > 2) { - fprintf(stderr, "This bootloader returns %d extra bytes in PID:", len); - for (i = 2; i <= len ; i++) - fprintf(stderr, " %02x", buf[i]); - fprintf(stderr, "\n"); - } - if (stm32_get_ack(stm) != STM32_ERR_OK) { - stm32_close(stm); - return NULL; - } - - stm->dev = devices; - while (stm->dev->id != 0x00 && stm->dev->id != stm->pid) - ++stm->dev; - - if (!stm->dev->id) { - fprintf(stderr, "Unknown/unsupported device (Device ID: 0x%03x)\n", stm->pid); - stm32_close(stm); - return NULL; - } - - return stm; -} - -void stm32_close(stm32_t *stm) -{ - if (stm) - free(stm->cmd); - free(stm); -} - -stm32_err_t stm32_read_memory(const stm32_t *stm, uint32_t address, - uint8_t data[], unsigned int len) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (!len) - return STM32_ERR_OK; - - if (len > 256) { - fprintf(stderr, "Error: READ length limit at 256 bytes\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->rm == STM32_CMD_ERR) { - fprintf(stderr, "Error: READ command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->rm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_send_command(stm, len - 1) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (port->read(port, data, len) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - return STM32_ERR_OK; -} - -stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, - const uint8_t data[], unsigned int len) -{ - struct port_interface *port = stm->port; - uint8_t cs, buf[256 + 2]; - unsigned int i, aligned_len; - stm32_err_t s_err; - - if (!len) - return STM32_ERR_OK; - - if (len > 256) { - fprintf(stderr, "Error: READ length limit at 256 bytes\n"); - return STM32_ERR_UNKNOWN; - } - - /* must be 32bit aligned */ - if (address & 0x3 || len & 0x3) { - fprintf(stderr, "Error: WRITE address and length must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->wm == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - /* send the address and checksum */ - if (stm32_send_command(stm, stm->cmd->wm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - aligned_len = (len + 3) & ~3; - cs = aligned_len - 1; - buf[0] = aligned_len - 1; - for (i = 0; i < len; i++) { - cs ^= data[i]; - buf[i + 1] = data[i]; - } - /* padding data */ - for (i = len; i < aligned_len; i++) { - cs ^= 0xFF; - buf[i + 1] = 0xFF; - } - buf[aligned_len + 1] = cs; - if (port->write(port, buf, aligned_len + 2) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_BLKWRITE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->wm != STM32_CMD_WM_NS) - stm32_warn_stretching("write"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_wunprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->uw == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE UNPROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->uw) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_WUNPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to WRITE UNPROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->uw != STM32_CMD_UW_NS) - stm32_warn_stretching("WRITE UNPROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_wprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->wp == STM32_CMD_ERR) { - fprintf(stderr, "Error: WRITE PROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->wp) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_WPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to WRITE PROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->wp != STM32_CMD_WP_NS) - stm32_warn_stretching("WRITE PROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_runprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->ur == STM32_CMD_ERR) { - fprintf(stderr, "Error: READOUT UNPROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->ur) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to READOUT UNPROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->ur != STM32_CMD_UR_NS) - stm32_warn_stretching("READOUT UNPROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_readprot_memory(const stm32_t *stm) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - - if (stm->cmd->rp == STM32_CMD_ERR) { - fprintf(stderr, "Error: READOUT PROTECT command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->rp) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - s_err = stm32_get_ack_timeout(stm, STM32_RPROT_TIMEOUT); - if (s_err == STM32_NACK) { - fprintf(stderr, "Error: Failed to READOUT PROTECT\n"); - return STM32_ERR_UNKNOWN; - } - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W - && stm->cmd->rp != STM32_CMD_RP_NS) - stm32_warn_stretching("READOUT PROTECT"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; -} - -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) -{ - struct port_interface *port = stm->port; - stm32_err_t s_err; - port_err_t p_err; - - if (!pages) - return STM32_ERR_OK; - - if (stm->cmd->er == STM32_CMD_ERR) { - fprintf(stderr, "Error: ERASE command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->er) != STM32_ERR_OK) { - fprintf(stderr, "Can't initiate chip erase!\n"); - return STM32_ERR_UNKNOWN; - } - - /* The erase command reported by the bootloader is either 0x43, 0x44 or 0x45 */ - /* 0x44 is Extended Erase, a 2 byte based protocol and needs to be handled differently. */ - /* 0x45 is clock no-stretching version of Extended Erase for I2C port. */ - if (stm->cmd->er != STM32_CMD_ER) { - /* Not all chips using Extended Erase support mass erase */ - /* Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range */ - /* So if someone has not overridden the default, but uses one of these chips, take it out of */ - /* mass erase mode, so it will be done page by page. This maximum might not be correct either! */ - if (stm->pid == 0x416 && pages == 0xFF) - pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ - - if (pages == 0xFF) { - uint8_t buf[3]; - - /* 0xFFFF the magic number for mass erase */ - buf[0] = 0xFF; - buf[1] = 0xFF; - buf[2] = 0x00; /* checksum */ - if (port->write(port, buf, 3) != PORT_ERR_OK) { - fprintf(stderr, "Mass erase error.\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Mass erase failed. Try specifying the number of pages to be erased.\n"); - if (port->flags & PORT_STRETCH_W - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } - - uint16_t pg_num; - uint8_t pg_byte; - uint8_t cs = 0; - uint8_t *buf; - int i = 0; - - buf = malloc(2 + 2 * pages + 1); - if (!buf) - return STM32_ERR_UNKNOWN; - - /* Number of pages to be erased - 1, two bytes, MSB first */ - pg_byte = (pages - 1) >> 8; - buf[i++] = pg_byte; - cs ^= pg_byte; - pg_byte = (pages - 1) & 0xFF; - buf[i++] = pg_byte; - cs ^= pg_byte; - - for (pg_num = spage; pg_num < spage + pages; pg_num++) { - pg_byte = pg_num >> 8; - cs ^= pg_byte; - buf[i++] = pg_byte; - pg_byte = pg_num & 0xFF; - cs ^= pg_byte; - buf[i++] = pg_byte; - } - buf[i++] = cs; - p_err = port->write(port, buf, i); - free(buf); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Page-by-page erase error.\n"); - return STM32_ERR_UNKNOWN; - } - - s_err = stm32_get_ack_timeout(stm, pages * STM32_SECTERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Page-by-page erase failed. Check the maximum pages your device supports.\n"); - if (port->flags & PORT_STRETCH_W - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - - return STM32_ERR_OK; - } - - /* And now the regular erase (0x43) for all other chips */ - if (pages == 0xFF) { - s_err = stm32_send_command_timeout(stm, 0xFF, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } else { - uint8_t cs = 0; - uint8_t pg_num; - uint8_t *buf; - int i = 0; - - buf = malloc(1 + pages + 1); - if (!buf) - return STM32_ERR_UNKNOWN; - - buf[i++] = pages - 1; - cs ^= (pages-1); - for (pg_num = spage; pg_num < (pages + spage); pg_num++) { - buf[i++] = pg_num; - cs ^= pg_num; - } - buf[i++] = cs; - p_err = port->write(port, buf, i); - free(buf); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Erase failed.\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } -} - -static stm32_err_t stm32_run_raw_code(const stm32_t *stm, - uint32_t target_address, - const uint8_t *code, uint32_t code_size) -{ - uint32_t stack_le = le_u32(0x20002000); - uint32_t code_address_le = le_u32(target_address + 8); - uint32_t length = code_size + 8; - uint8_t *mem, *pos; - uint32_t address, w; - - /* Must be 32-bit aligned */ - if (target_address & 0x3) { - fprintf(stderr, "Error: code address must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - mem = malloc(length); - if (!mem) - return STM32_ERR_UNKNOWN; - - memcpy(mem, &stack_le, sizeof(uint32_t)); - memcpy(mem + 4, &code_address_le, sizeof(uint32_t)); - memcpy(mem + 8, code, code_size); - - pos = mem; - address = target_address; - while (length > 0) { - w = length > 256 ? 256 : length; - if (stm32_write_memory(stm, address, pos, w) != STM32_ERR_OK) { - free(mem); - return STM32_ERR_UNKNOWN; - } - - address += w; - pos += w; - length -= w; - } - - free(mem); - return stm32_go(stm, target_address); -} - -stm32_err_t stm32_go(const stm32_t *stm, uint32_t address) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (stm->cmd->go == STM32_CMD_ERR) { - fprintf(stderr, "Error: GO command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->go) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - return STM32_ERR_OK; -} - -stm32_err_t stm32_reset_device(const stm32_t *stm) -{ - uint32_t target_address = stm->dev->ram_start; - - return stm32_run_raw_code(stm, target_address, stm_reset_code, stm_reset_code_length); -} - -stm32_err_t stm32_crc_memory(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc) -{ - struct port_interface *port = stm->port; - uint8_t buf[5]; - - if (address & 0x3 || length & 0x3) { - fprintf(stderr, "Start and end addresses must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->crc == STM32_CMD_ERR) { - fprintf(stderr, "Error: CRC command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (stm32_send_command(stm, stm->cmd->crc) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = address >> 24; - buf[1] = (address >> 16) & 0xFF; - buf[2] = (address >> 8) & 0xFF; - buf[3] = address & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - buf[0] = length >> 24; - buf[1] = (length >> 16) & 0xFF; - buf[2] = (length >> 8) & 0xFF; - buf[3] = length & 0xFF; - buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3]; - if (port->write(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (stm32_get_ack(stm) != STM32_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (port->read(port, buf, 5) != PORT_ERR_OK) - return STM32_ERR_UNKNOWN; - - if (buf[4] != (buf[0] ^ buf[1] ^ buf[2] ^ buf[3])) - return STM32_ERR_UNKNOWN; - - *crc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; - return STM32_ERR_OK; -} - -/* - * CRC computed by STM32 is similar to the standard crc32_be() - * implemented, for example, in Linux kernel in ./lib/crc32.c - * But STM32 computes it on units of 32 bits word and swaps the - * bytes of the word before the computation. - * Due to byte swap, I cannot use any CRC available in existing - * libraries, so here is a simple not optimized implementation. - */ -#define CRCPOLY_BE 0x04c11db7 -#define CRC_MSBMASK 0x80000000 -#define CRC_INIT_VALUE 0xFFFFFFFF -uint32_t stm32_sw_crc(uint32_t crc, uint8_t *buf, unsigned int len) -{ - int i; - uint32_t data; - - if (len & 0x3) { - fprintf(stderr, "Buffer length must be multiple of 4 bytes\n"); - return 0; - } - - while (len) { - data = *buf++; - data |= *buf++ << 8; - data |= *buf++ << 16; - data |= *buf++ << 24; - len -= 4; - - crc ^= data; - - for (i = 0; i < 32; i++) - if (crc & CRC_MSBMASK) - crc = (crc << 1) ^ CRCPOLY_BE; - else - crc = (crc << 1); - } - return crc; -} - -stm32_err_t stm32_crc_wrapper(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc) -{ - uint8_t buf[256]; - uint32_t start, total_len, len, current_crc; - - if (address & 0x3 || length & 0x3) { - fprintf(stderr, "Start and end addresses must be 4 byte aligned\n"); - return STM32_ERR_UNKNOWN; - } - - if (stm->cmd->crc != STM32_CMD_ERR) - return stm32_crc_memory(stm, address, length, crc); - - start = address; - total_len = length; - current_crc = CRC_INIT_VALUE; - while (length) { - len = length > 256 ? 256 : length; - if (stm32_read_memory(stm, address, buf, len) != STM32_ERR_OK) { - fprintf(stderr, - "Failed to read memory at address 0x%08x, target write-protected?\n", - address); - return STM32_ERR_UNKNOWN; - } - current_crc = stm32_sw_crc(current_crc, buf, len); - length -= len; - address += len; - - fprintf(stderr, - "\rCRC address 0x%08x (%.2f%%) ", - address, - (100.0f / (float)total_len) * (float)(address - start) - ); - fflush(stderr); - } - fprintf(stderr, "Done.\n"); - *crc = current_crc; - return STM32_ERR_OK; -} diff --git a/win/src/stm32flash_serial/src/stm32.h b/win/src/stm32flash_serial/src/stm32.h deleted file mode 100644 index 1688fcb4b..000000000 --- a/win/src/stm32flash_serial/src/stm32.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _STM32_H -#define _STM32_H - -#include -#include "serial.h" - -#define STM32_MAX_RX_FRAME 256 /* cmd read memory */ -#define STM32_MAX_TX_FRAME (1 + 256 + 1) /* cmd write memory */ - -typedef enum { - STM32_ERR_OK = 0, - STM32_ERR_UNKNOWN, /* Generic error */ - STM32_ERR_NACK, - STM32_ERR_NO_CMD, /* Command not available in bootloader */ -} stm32_err_t; - -typedef struct stm32 stm32_t; -typedef struct stm32_cmd stm32_cmd_t; -typedef struct stm32_dev stm32_dev_t; - -struct stm32 { - const serial_t *serial; - struct port_interface *port; - uint8_t bl_version; - uint8_t version; - uint8_t option1, option2; - uint16_t pid; - stm32_cmd_t *cmd; - const stm32_dev_t *dev; -}; - -struct stm32_dev { - uint16_t id; - const char *name; - uint32_t ram_start, ram_end; - uint32_t fl_start, fl_end; - uint16_t fl_pps; // pages per sector - uint16_t fl_ps; // page size - uint32_t opt_start, opt_end; - uint32_t mem_start, mem_end; -}; - -stm32_t *stm32_init(struct port_interface *port, const char init); -void stm32_close(stm32_t *stm); -stm32_err_t stm32_read_memory(const stm32_t *stm, uint32_t address, - uint8_t data[], unsigned int len); -stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, - const uint8_t data[], unsigned int len); -stm32_err_t stm32_wunprot_memory(const stm32_t *stm); -stm32_err_t stm32_wprot_memory(const stm32_t *stm); -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, - uint8_t pages); -stm32_err_t stm32_go(const stm32_t *stm, uint32_t address); -stm32_err_t stm32_reset_device(const stm32_t *stm); -stm32_err_t stm32_readprot_memory(const stm32_t *stm); -stm32_err_t stm32_runprot_memory(const stm32_t *stm); -stm32_err_t stm32_crc_memory(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc); -stm32_err_t stm32_crc_wrapper(const stm32_t *stm, uint32_t address, - uint32_t length, uint32_t *crc); -uint32_t stm32_sw_crc(uint32_t crc, uint8_t *buf, unsigned int len); - -#endif - diff --git a/win/src/stm32flash_serial/src/stm32flash.1 b/win/src/stm32flash_serial/src/stm32flash.1 deleted file mode 100644 index d37292f6a..000000000 --- a/win/src/stm32flash_serial/src/stm32flash.1 +++ /dev/null @@ -1,407 +0,0 @@ -.TH STM32FLASH 1 "2013\-11\-03" STM32FLASH "User command" -.SH NAME -stm32flash \- flashing utility for STM32 and STM32W through UART or I2C -.SH SYNOPSIS -.B stm32flash -.RB [ \-cfhjkouvCR ] -.RB [ \-a -.IR bus_address ] -.RB [ \-b -.IR baud_rate ] -.RB [ \-m -.IR serial_mode ] -.RB [ \-r -.IR filename ] -.RB [ \-w -.IR filename ] -.RB [ \-e -.IR num ] -.RB [ \-n -.IR count ] -.RB [ \-g -.IR address ] -.RB [ \-s -.IR start_page ] -.RB [ \-S -.IR address [: length ]] -.RB [ \-F -.IR RX_length [: TX_length ]] -.RB [ \-i -.IR GPIO_string ] -.RI [ tty_device -.R | -.IR i2c_device ] - -.SH DESCRIPTION -.B stm32flash -reads or writes the flash memory of STM32 and STM32W. - -It requires the STM32[W] to embed a bootloader compliant with ST -application note AN3155. -.B stm32flash -uses the serial port -.I tty_device -to interact with the bootloader of STM32[W]. - -.SH OPTIONS -.TP -.BI "\-a" " bus_address" -Specify address on bus for -.IR i2c_device . -This option is mandatory for I2C interface. - -.TP -.BI "\-b" " baud_rate" -Specify baud rate speed of -.IR tty_device . -Please notice that the ST bootloader can automatically detect the baud rate, -as explaned in chapter 2 of AN3155. -This option could be required together with option -.B "\-c" -or if following interaction with bootloader is expected. -Default is -.IR 57600 . - -.TP -.BI "\-m" " mode" -Specify the format of UART data. -.I mode -is a three characters long string where each character specifies, in -this strict order, character size, parity and stop bits. -The only values currenly used are -.I 8e1 -for standard STM32 bootloader and -.I 8n1 -for standard STM32W bootloader. -Default is -.IR 8e1 . - -.TP -.BI "\-r" " filename" -Specify to read the STM32[W] flash and write its content in -.I filename -in raw binary format (see below -.BR "FORMAT CONVERSION" ). - -.TP -.BI "\-w" " filename" -Specify to write the STM32[W] flash with the content of -.IR filename . -File format can be either raw binary or intel hex (see below -.BR "FORMAT CONVERSION" ). -The file format is automatically detected. -To by\-pass format detection and force binary mode (e.g. to -write an intel hex content in STM32[W] flash), use -.B \-f -option. - -.TP -.B \-u -Specify to disable write\-protection from STM32[W] flash. -The STM32[W] will be reset after this operation. - -.TP -.B \-j -Enable the flash read\-protection. - -.TP -.B \-k -Disable the flash read\-protection. - -.TP -.B \-o -Erase only. - -.TP -.BI "\-e" " num" -Specify to erase only -.I num -pages before writing the flash. Default is to erase the whole flash. With -.B \-e 0 -the flash would not be erased. - -.TP -.B \-v -Specify to verify flash content after write operation. - -.TP -.BI "\-n" " count" -Specify to retry failed writes up to -.I count -times. Default is 10 times. - -.TP -.BI "\-g" " address" -Specify address to start execution from (0 = flash start). - -.TP -.BI "\-s" " start_page" -Specify flash page offset (0 = flash start). - -.TP -.BI "\-S" " address" "[:" "length" "]" -Specify start address and optionally length for read/write/erase/crc operations. - -.TP -.BI "\-F" " RX_length" "[:" "TX_length" "]" -Specify the maximum frame size for the current interface. -Due to STM32 bootloader protocol, host will never handle frames bigger than -256 byte in RX or 258 byte in TX. -Due to current code, lowest limit in RX is 20 byte (to read a complete reply -of command GET). Minimum limit in TX is 5 byte, required by protocol. - -.TP -.B \-f -Force binary parser while reading file with -.BR "\-w" "." - -.TP -.B \-h -Show help. - -.TP -.B \-c -Specify to resume the existing UART connection and don't send initial -INIT sequence to detect baud rate. Baud rate must be kept the same as the -existing connection. This is useful if the reset fails. - -.TP -.BI "\-i" " GPIO_string" -Specify the GPIO sequences on the host to force STM32[W] to enter and -exit bootloader mode. GPIO can either be real GPIO connected from host to -STM32[W] beside the UART connection, or UART's modem signals used as -GPIO. (See below -.B BOOTLOADER GPIO SEQUENCE -for the format of -.I GPIO_string -and further explanation). - -.TP -.B \-C -Specify to compute CRC on memory content. -By default the CRC is computed on the whole flash content. -Use -.B "\-S" -to provide different memory address range. - -.TP -.B \-R -Specify to reset the device at exit. -This option is ignored if either -.BR "\-g" "," -.BR "\-j" "," -.B "\-k" -or -.B "\-u" -is also specified. - -.SH BOOTLOADER GPIO SEQUENCE -This feature is currently available on Linux host only. - -As explained in ST application note AN2606, after reset the STM32 will -execute either the application program in user flash or the bootloader, -depending on the level applied at specific pins of STM32 during reset. - -STM32 bootloader is automatically activated by configuring the pins -BOOT0="high" and BOOT1="low" and then by applying a reset. -Application program in user flash is activated by configuring the pin -BOOT0="low" (the level on BOOT1 is ignored) and then by applying a reset. - -When GPIO from host computer are connected to either configuration and -reset pins of STM32, -.B stm32flash -can control the host GPIO to reset STM32 and to force execution of -bootloader or execution of application program. - -The sequence of GPIO values to entry to and exit from bootloader mode is -provided with command line option -.B "\-i" -.IR "GPIO_string" . - -.PD 0 -The format of -.IR "GPIO_string" " is:" -.RS -GPIO_string = [entry sequence][:[exit sequence]] -.P -sequence = [\-]n[,sequence] -.RE -.P -In the above sequences, negative numbers correspond to GPIO at "low" level; -numbers without sign correspond to GPIO at "high" level. -The value "n" can either be the GPIO number on the host system or the -string "rts", "dtr" or "brk". The strings "rts" and "dtr" drive the -corresponding UART's modem lines RTS and DTR as GPIO. -The string "brk" forces the UART to send a BREAK sequence on TX line; -after BREAK the UART is returned in normal "non\-break" mode. -Note: the string "\-brk" has no effect and is ignored. -.PD - -.PD 0 -As example, let's suppose the following connection between host and STM32: -.IP \(bu 2 -host GPIO_3 connected to reset pin of STM32; -.IP \(bu 2 -host GPIO_4 connected to STM32 pin BOOT0; -.IP \(bu 2 -host GPIO_5 connected to STM32 pin BOOT1. -.PD -.P - -In this case, the sequence to enter in bootloader mode is: first put -GPIO_4="high" and GPIO_5="low"; then send reset pulse by GPIO_3="low" -followed by GPIO_3="high". -The corresponding string for -.I GPIO_string -is "4,\-5,\-3,3". - -To exit from bootloade and run the application program, the sequence is: -put GPIO_4="low"; then send reset pulse. -The corresponding string for -.I GPIO_string -is "\-4,\-3,3". - -The complete command line flag is "\-i 4,\-5,\-3,3:\-4,\-3,3". - -STM32W uses pad PA5 to select boot mode; if during reset PA5 is "low" then -STM32W will enter in bootloader mode; if PA5 is "high" it will execute the -program in flash. - -As example, supposing GPIO_3 connected to PA5 and GPIO_2 to STM32W's reset. -The command: -.PD 0 -.RS -stm32flash \-i \-3,\-2,2:3,\-2,2 /dev/ttyS0 -.RE -provides: -.IP \(bu 2 -entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high -.IP \(bu 2 -exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high -.PD - -.SH EXAMPLES -Get device information: -.RS -.PD 0 -.P -stm32flash /dev/ttyS0 -.PD -.RE - -Write with verify and then start execution: -.RS -.PD 0 -.P -stm32flash \-w filename \-v \-g 0x0 /dev/ttyS0 -.PD -.RE - -Read flash to file: -.RS -.PD 0 -.P -stm32flash \-r filename /dev/ttyS0 -.PD -.RE - -Start execution: -.RS -.PD 0 -.P -stm32flash \-g 0x0 /dev/ttyS0 -.PD -.RE - -Specify: -.PD 0 -.IP \(bu 2 -entry sequence: RTS=low, DTR=low, DTR=high -.IP \(bu 2 -exit sequence: RTS=high, DTR=low, DTR=high -.P -.RS -stm32flash \-i \-rts,\-dtr,dtr:rts,\-dtr,dtr /dev/ttyS0 -.PD -.RE - -.SH FORMAT CONVERSION -Flash images provided by ST or created with ST tools are often in file -format Motorola S\-Record. -Conversion between raw binary, intel hex and Motorola S\-Record can be -done through software package SRecord. - -.SH AUTHORS -The original software package -.B stm32flash -is written by -.I Geoffrey McRae -and is since 2012 maintained by -.IR "Tormod Volden " . - -Man page and extension to STM32W and I2C are written by -.IR "Antonio Borneo " . - -Please report any bugs at the project homepage -http://stm32flash.googlecode.com . - -.SH SEE ALSO -.BR "srec_cat" "(1)," " srec_intel" "(5)," " srec_motorola" "(5)." - -The communication protocol used by ST bootloader is documented in -following ST application notes, depending on communication port. -The current version of -.B stm32flash -only supports -.I UART -and -.I I2C -ports. -.PD 0 -.P -.IP \(bu 2 -AN3154: CAN protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/CD00264321.pdf -.RE - -.P -.IP \(bu 2 -AN3155: USART protocol used in the STM32(TM) bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/CD00264342.pdf -.RE - -.P -.IP \(bu 2 -AN4221: I2C protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/DM00072315.pdf -.RE - -.P -.IP \(bu 2 -AN4286: SPI protocol used in the STM32 bootloader -.P -.RS -http://www.st.com/web/en/resource/technical/document/application_note/DM00081379.pdf -.RE - -.PD - - -Boot mode selection for STM32 is documented in ST application note -AN2606, available from the ST website: -.PD 0 -.P -http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf -.PD - -.SH LICENSE -.B stm32flash -is distributed under GNU GENERAL PUBLIC LICENSE Version 2. -Copy of the license is available within the source code in the file -.IR "gpl\-2.0.txt" . diff --git a/win/src/stm32flash_serial/src/utils.c b/win/src/stm32flash_serial/src/utils.c deleted file mode 100644 index 271bb3ed7..000000000 --- a/win/src/stm32flash_serial/src/utils.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include "utils.h" - -/* detect CPU endian */ -char cpu_le() { - const uint32_t cpu_le_test = 0x12345678; - return ((const unsigned char*)&cpu_le_test)[0] == 0x78; -} - -uint32_t be_u32(const uint32_t v) { - if (cpu_le()) - return ((v & 0xFF000000) >> 24) | - ((v & 0x00FF0000) >> 8) | - ((v & 0x0000FF00) << 8) | - ((v & 0x000000FF) << 24); - return v; -} - -uint32_t le_u32(const uint32_t v) { - if (!cpu_le()) - return ((v & 0xFF000000) >> 24) | - ((v & 0x00FF0000) >> 8) | - ((v & 0x0000FF00) << 8) | - ((v & 0x000000FF) << 24); - return v; -} diff --git a/win/src/stm32flash_serial/src/utils.h b/win/src/stm32flash_serial/src/utils.h deleted file mode 100644 index a8d37d2d5..000000000 --- a/win/src/stm32flash_serial/src/utils.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef _H_UTILS -#define _H_UTILS - -#include - -char cpu_le(); -uint32_t be_u32(const uint32_t v); -uint32_t le_u32(const uint32_t v); - -#endif diff --git a/win/stm32flash.exe b/win/stm32flash.exe index 911c0cc05..d48eddec6 100644 Binary files a/win/stm32flash.exe and b/win/stm32flash.exe differ