Skip to content

Commit

Permalink
Merge pull request #53 from drowe67/dr-sm1000
Browse files Browse the repository at this point in the history
Windows DFU cleanup, thanks everyone :-)
  • Loading branch information
drowe67 committed Jul 18, 2019
2 parents 082fbe5 + 195a989 commit 9c4d23d
Show file tree
Hide file tree
Showing 8 changed files with 3,418 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -5,3 +5,4 @@ stm32/unittest/lib/python/__pycache__/
stm32/unittest/src/libstm32f4.a
stm32/unittest/src/*.map
stm32/unittest/test_run/
*.pyc
11 changes: 11 additions & 0 deletions stm32/CMakeLists.txt
Expand Up @@ -109,6 +109,16 @@ macro(elf2bin target)
ADDITIONAL_MAKE_CLEAN_FILES ${target}.bin)
endmacro()

# Macro for elf->bin
macro(elf2dfu target)
add_custom_command(TARGET ${target}
POST_BUILD COMMAND ${CMAKE_OBJCOPY} -O ihex ${target}.elf ${target}.hex && ${CMAKE_SOURCE_DIR}/support/hex2dfu.py ${target}.hex ${target}.dfu
COMMENT "Creating dfu file for ${target}")
set_source_files_properties(${target}.bin PROPERTIES GENERATED TRUE)
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES ${target}.hex ${target}.dfu)
endmacro()

# This macro just adds generation of a map file with the same name as the executable and .map suffix
# to the linker command line. This works in older Cmake version (versions >= 3.13 have target_link_options)
# it should be a one to one replacement for add_executable
Expand Down Expand Up @@ -399,6 +409,7 @@ add_mapped_executable(sm1000v2 ${SM1000_SRCS} ${SYSTEM_SRCS})
target_link_libraries(sm1000v2 stm32f4_adac stm32f4 CMSIS)
target_compile_options(sm1000v2 PRIVATE "-O3")
elf2bin(sm1000v2)
elf2dfu(sm1000v2)

set(FREEDV_TX_PROFILE_SRCS
src/freedv_tx_profile.c
Expand Down
33 changes: 17 additions & 16 deletions stm32/doc/sm1000_manual.md
Expand Up @@ -100,27 +100,28 @@ Settings are saved when you hold down BACK to leave the root menu.

You can program the flash memory on your SM1000 via USB using a Windows or Linux PC. Download the latest SM1000 firmware here:

Version | Date | Download | Notes
:---: | --- | --- | ---
1 | May 2015 | [sm1000.bin](http://www.rowetel.com/downloads/codec2/smartmic/sm1000.bin) | FreeDV 1600
2 | July 2019 | [sm1000v2.bin](http://www.rowetel.com/downloads/codec2/smartmic/sm1000v2.bin) | Morse menus and FreeDV 700D
Version | Date | Download .bin | Download .dfu
:---: | --- | --- | --- |
1 | May 2015 | [sm1000.bin](http://www.rowetel.com/downloads/codec2/smartmic/sm1000.bin)
2 | July 2019 | [sm1000v2.bin](http://www.rowetel.com/downloads/codec2/smartmic/sm1000v2.bin) | [sm1000v2.dfu](http://www.rowetel.com/downloads/codec2/smartmic/sm1000v2.dfu)

## Windows

Flashing on Windows is a two step process:
1. Create sm1000.dfu from sm1000.bin
1. Flash sm1000.dfu
Find and install the **DfuSeDemo** software by searching on the [ST web site](http://www.st.com).

Find and install the **DfuSeDemo** software by searching the [ST web site](http://www.st.com).
For Windows use the ```.dfu``` firmware file provided above:

Here are the steps:
1. Apply power with PTT held down, then release PTT. Connect the SM1000 to a Windows PC.
1. To create an image in the DFU format: Upload Action (to create a DFU file image). Choose, and then enter a file name to save the image. Select Upload, and select Yes.
1. To Flash: Choose, to select the DFU flash file image. Select Upgrade to start the process, and select Yes.
1. It will begin the erase process, then the flash. It should see a message when completed that it was successful
1. Power cycle the SM1000 and the new firmware will run.

Thanks Walter K5WH for this procedure.
1. Connect the SM1000 USB to a Windows PC.
1. Run the ```DfuSeDemo``` Application.
1. Apply power with PTT held down, then release PTT.
1. The ```Available DFU Devices``` window should show ```STM Device in DFU Mode```. If not, use the arrow to select that option. Verify it shows a ```Vender ID``` of 0483, and a ```Product ID``` of DF11.
1. In the lower right quadrant of the screen, under ```Upgrade or Verify Action``` select ```Choose```.
1. Locate your DFU file you want to program into the SM1000, and press ```Open```.
1. Select ```Verify after download``` option.
1. Select ```Upgrade``` and confirm ```Yes``` when asked, and the firmware procedure will commence.
1. A message when complete that it was successful. If the message returns that it was unsuccessful, then first try the ```Upgrade``` again. If the upgrade fails twice, you may have to start this complete procedure again.

Power cycle the SM1000 and the new firmware will run.

## Linux

Expand Down
206 changes: 206 additions & 0 deletions stm32/support/hex2dfu.py
@@ -0,0 +1,206 @@
#!/usr/bin/env python2
#
# Intel HEX to ST microelectronics DfuSe file converter
# Copyright (C)2015 Thomas Kindler <mail@t-kindler.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
import struct
import argparse
from zlib import crc32
from intelhex import IntelHex


def load_hex():
"""
Load hex or binary file.
:return: intelhex object
"""
if args.verbose:
print "Loading %s..." % args.source

try:
ih = IntelHex()

if args.format == "hex":
ih.loadhex(args.source)
else:
ih.loadbin(args.source, args.start_addr)

except Exception, e:
print e
exit(1)

if args.verbose:
print " Start: 0x%08x" % ih.minaddr()
print " End : 0x%08x" % ih.maxaddr()

return ih


def save_dfu(ih):
"""
Save as STMicroelectronics DfuSe file.
see UM0391 - DfuSe File Format Specification
:param ih: intelhex object
"""
if args.verbose:
print "Saving %s..." % args.target
print " Device ID: 0x%04x:0x%04x" % (args.vid, args.pid)
print " Target name: %s" % args.target_name

# Image element
#
image_data = ih.tobinstr()

data = struct.pack(
"<II",
ih.minaddr(), # dwElementAddress
len(image_data) # dwElementSize
) + image_data # Data

# Target prefix
#
szTargetName = args.target_name.encode("ascii")

data = struct.pack(
"<6sBI255sII",
b"Target", # szSignature
0, # bAlternateSetting
1, # bTargetNamed
szTargetName, # szTargetName
len(data), # dwTargetSize
1 # dwNbElements
) + data

# Prefix
#
data = struct.pack(
"<5sBIB",
b"DfuSe", # szSignature
0x01, # bVersion,
len(data)+11, # DFUImageSize,
1 # bTargets
) + data

# Suffix
#
data += struct.pack(
"<HHHH3sB",
0xFFFF, # bcdDevice
args.pid, # idProduct
args.vid, # idVendor
0x011a, # bdcDFU
b"UFD", # ucDfuSignature
16 # bLength
)

dwCRC = ~crc32(data) & 0xFFFFFFFF

data += struct.pack(
"<I",
dwCRC # dwCRC
)

try:
open(args.target, "wb").write(data)

except Exception, e:
print e
exit(1)


# Parse arguments
#
DEFAULT_DEVICE = "0x0483:0xdf11"

parser = argparse.ArgumentParser(
description="Convert hex files to STMicroelectronics DfuSe format"
)

parser.add_argument(
"--version",
action="version",
version="%(prog)s 1.1.0"
)

parser.add_argument(
"-q", "--quiet", dest="verbose",
default=True,
action="store_false",
help="do not print status messages"
)

parser.add_argument(
"source", help="source file"
)

parser.add_argument(
"target", nargs = "?",
help="target file"
)

parser.add_argument(
"-f", "--format",
default="hex", choices=["hex", "bin"],
help="source file format (default: %(default)s)"
)

parser.add_argument(
"-s", "--start", dest="start_addr",
help="set start address (for bin files)"
)

parser.add_argument(
"-d", "--device",
default=DEFAULT_DEVICE,
help="device VID:PID (default: %(default)s)"
)

parser.add_argument(
"-n", "--name", dest="target_name",
default="application",
help="target name (default: %(default)s)"
)

args=parser.parse_args()

# Check arguments
#
if args.target == None:
(root, ext) = os.path.splitext(args.source)
args.target = root + ".dfu"


if args.format == "bin":
if args.start_addr == None:
print "option --start required for binary files"
exit(1)

args.start_addr = int(args.start_addr, 0)
else:
if args.start_addr != None:
print "option --start not allowed for hex files"
exit(1)


args.vid = int(args.device.split(':', 1)[0], 0)
args.pid = int(args.device.split(':', 1)[1], 0)


# Convert file
#
save_dfu( load_hex() )

0 comments on commit 9c4d23d

Please sign in to comment.