mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-17 21:58:33 +03:00
Compare commits
244 Commits
kredon/sim
...
laforge/wi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a6dcf2a27 | ||
|
|
61a01b77f6 | ||
|
|
0b28031312 | ||
|
|
4e9beae46a | ||
|
|
823f453d83 | ||
|
|
13cb311c06 | ||
|
|
e6806e58c2 | ||
|
|
37220cce25 | ||
|
|
02712376df | ||
|
|
baa62777c8 | ||
|
|
1fad9229bf | ||
|
|
c7173bcc69 | ||
|
|
02f01e859c | ||
|
|
575214f248 | ||
|
|
e88be9e782 | ||
|
|
b6e2f0f8e7 | ||
|
|
34200e4676 | ||
|
|
e3b2de45c4 | ||
|
|
ce4b5c25e8 | ||
|
|
7f7de1ec1d | ||
|
|
8591495d74 | ||
|
|
b566ea3e83 | ||
|
|
563601cff2 | ||
|
|
e9556efe88 | ||
|
|
cdc0853777 | ||
|
|
bfd27afd5f | ||
|
|
17cda3db8a | ||
|
|
e213cc4f59 | ||
|
|
a5bbe78d2d | ||
|
|
140f007c3e | ||
|
|
12c9b7ba02 | ||
|
|
4d4405ff3a | ||
|
|
6a3a714e2f | ||
|
|
e9f429d34c | ||
|
|
02d0d73cf1 | ||
|
|
5b136021d8 | ||
|
|
81f4ef7750 | ||
|
|
fa197ca343 | ||
|
|
e92cb50a6e | ||
|
|
1714679106 | ||
|
|
a812de808d | ||
|
|
b0b457df63 | ||
|
|
ad117091ca | ||
|
|
56be0bf317 | ||
|
|
60118315cc | ||
|
|
63c9e1f402 | ||
|
|
7c1d85eb4d | ||
|
|
587248404c | ||
|
|
f620c3978c | ||
|
|
a14616c096 | ||
|
|
f4a625be53 | ||
|
|
271be9d181 | ||
|
|
342a7fe039 | ||
|
|
3c003cc2fa | ||
|
|
37055b9286 | ||
|
|
75a5f224c0 | ||
|
|
198c3fb21b | ||
|
|
98cf47adba | ||
|
|
87940f1f83 | ||
|
|
36f888f8b5 | ||
|
|
0a7c691b90 | ||
|
|
c9af72dccb | ||
|
|
d70836f965 | ||
|
|
ed3ceec56f | ||
|
|
15f48b2e89 | ||
|
|
503e184157 | ||
|
|
24c6fe21ab | ||
|
|
8cbede7067 | ||
|
|
8b6991c18c | ||
|
|
1cfc25e8c1 | ||
|
|
3864a794b4 | ||
|
|
e051ddd1f3 | ||
|
|
98fbf23897 | ||
|
|
9b367872c8 | ||
|
|
0b7e5f3af0 | ||
|
|
72a62cfdb9 | ||
|
|
483a3203fb | ||
|
|
71cfc2b90d | ||
|
|
15e943ab8b | ||
|
|
b7f94dcb9f | ||
|
|
c90de6983c | ||
|
|
6f41349db9 | ||
|
|
208890ad6e | ||
|
|
964cda309d | ||
|
|
331fa5a237 | ||
|
|
6fada5604b | ||
|
|
931fe558df | ||
|
|
d401b12136 | ||
|
|
389a4040d5 | ||
|
|
5db9402a5f | ||
|
|
ac7e73a579 | ||
|
|
7233cf803a | ||
|
|
cdcdcc9f6d | ||
|
|
e876bf53e8 | ||
|
|
f7f1ea864d | ||
|
|
3feadfa910 | ||
|
|
9acff5ee5a | ||
|
|
e5efbb156c | ||
|
|
ede87e067d | ||
|
|
acb7bd9fbe | ||
|
|
4b487b836a | ||
|
|
e0265462d8 | ||
|
|
d14970f95b | ||
|
|
b1a81c130e | ||
|
|
298a5ba722 | ||
|
|
c3ef475ea5 | ||
|
|
155f57abcf | ||
|
|
bc62335768 | ||
|
|
63490361d2 | ||
|
|
6228d187da | ||
|
|
a634c0efee | ||
|
|
bb9b0dc8e8 | ||
|
|
b7e326cad3 | ||
|
|
2fdcf3b38d | ||
|
|
7e5cda5732 | ||
|
|
032fc5f844 | ||
|
|
b1f99c909c | ||
|
|
53b4e593aa | ||
|
|
dc85fbc3e1 | ||
|
|
66ffb6d493 | ||
|
|
5b5d24ebf3 | ||
|
|
faf1e88e48 | ||
|
|
64f69fc4ac | ||
|
|
6303c39a00 | ||
|
|
ad0958e9e3 | ||
|
|
4f3a0356a4 | ||
|
|
7d5d011095 | ||
|
|
1dbcf62295 | ||
|
|
e5f891a825 | ||
|
|
a6bd7178b5 | ||
|
|
ba15387b09 | ||
|
|
c171112994 | ||
|
|
29200c6223 | ||
|
|
80d9476602 | ||
|
|
e2b0f971e5 | ||
|
|
e07640c35a | ||
|
|
82b628524f | ||
|
|
cb78b55c26 | ||
|
|
77ff745cca | ||
|
|
bd9d94994d | ||
|
|
95fac3aeab | ||
|
|
c17bf77ecc | ||
|
|
c394109964 | ||
|
|
888f196595 | ||
|
|
f7f61cd10f | ||
|
|
0e95f53588 | ||
|
|
76ef811a4e | ||
|
|
fecfa2aa51 | ||
|
|
c428516efa | ||
|
|
37e7861c4d | ||
|
|
ff3d84922d | ||
|
|
9547e419eb | ||
|
|
8daba9cc9a | ||
|
|
d5f583da60 | ||
|
|
04ccb770fd | ||
|
|
910e6830b9 | ||
|
|
9cccb2bab5 | ||
|
|
8a4fba5ea2 | ||
|
|
1b39fd31ee | ||
|
|
0f4abf5eaa | ||
|
|
1836ac0761 | ||
|
|
dd36d9b010 | ||
|
|
8b8e58b00e | ||
|
|
8f70c3eb1f | ||
|
|
ebe672e926 | ||
|
|
d8ebd6ab77 | ||
|
|
738a04aefb | ||
|
|
2a44dc598d | ||
|
|
ec396bf402 | ||
|
|
697199676e | ||
|
|
8e84f8125c | ||
|
|
d1c6536154 | ||
|
|
352809992c | ||
|
|
a71a6f48cb | ||
|
|
57b60d23cf | ||
|
|
b60538888f | ||
|
|
680bdaba96 | ||
|
|
f66af0c640 | ||
|
|
5f6b8717a4 | ||
|
|
ac0843af83 | ||
|
|
31ed8029b7 | ||
|
|
3b7624c120 | ||
|
|
f000831d72 | ||
|
|
b37bda0b55 | ||
|
|
c6b968067d | ||
|
|
a95bb1e85d | ||
|
|
da5578bd85 | ||
|
|
d975411511 | ||
|
|
a2fccba96c | ||
|
|
411428eb5e | ||
|
|
f82f0f6eff | ||
|
|
55f0612c8e | ||
|
|
33d1eb73fd | ||
|
|
93717e43b3 | ||
|
|
9a12d68c74 | ||
|
|
efbcf38afb | ||
|
|
9918c2840e | ||
|
|
d24e9bde26 | ||
|
|
2bdaa73aff | ||
|
|
fcf2743552 | ||
|
|
d44cb80bc5 | ||
|
|
9e29a3eb37 | ||
|
|
bf6b1b1a3e | ||
|
|
4cbdc7cf18 | ||
|
|
86f48fc962 | ||
|
|
1200a5228f | ||
|
|
fe763b7698 | ||
|
|
c9bd715289 | ||
|
|
35e8bdf879 | ||
|
|
709a431ab9 | ||
|
|
30f90a78fc | ||
|
|
7406337a7f | ||
|
|
6e3f1121e6 | ||
|
|
de97fd25bd | ||
|
|
012940f48e | ||
|
|
e2f84f6a8b | ||
|
|
4d6a4b949c | ||
|
|
a1012b170a | ||
|
|
42bd026416 | ||
|
|
638cec820f | ||
|
|
00ec89d73f | ||
|
|
cf59919494 | ||
|
|
11914d9658 | ||
|
|
3113e3d2e5 | ||
|
|
9def7631ba | ||
|
|
ca9e4bf4ba | ||
|
|
8210ec3f62 | ||
|
|
8fa6ff5979 | ||
|
|
866d20b10e | ||
|
|
4fe99fad59 | ||
|
|
7be52ec1ce | ||
|
|
a2b367633c | ||
|
|
927ffb46eb | ||
|
|
d7a6de57d2 | ||
|
|
353351ddf4 | ||
|
|
4091d78c4b | ||
|
|
ee62a9da56 | ||
|
|
45ad62d8d4 | ||
|
|
2c4e2af21f | ||
|
|
7b73462442 | ||
|
|
36abece0b1 | ||
|
|
f9997e9d26 | ||
|
|
05cc7f6531 | ||
|
|
46893451de |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,3 +21,4 @@ host/simtrace2-list
|
|||||||
host/simtrace2-remsim
|
host/simtrace2-remsim
|
||||||
host/simtrace2-remsim-usb2udp
|
host/simtrace2-remsim-usb2udp
|
||||||
usb_strings_generated.h
|
usb_strings_generated.h
|
||||||
|
firmware/usbstring/usbstring
|
||||||
|
|||||||
32
Makefile
Normal file
32
Makefile
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
all: fw utils
|
||||||
|
|
||||||
|
define RULES
|
||||||
|
fw-$(1)-$(2):
|
||||||
|
make -C firmware BOARD=$(1) APP=$(2)
|
||||||
|
fw-$(1)-$(2)-clean:
|
||||||
|
make -C firmware BOARD=$(1) APP=$(2) clean
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call RULES,simtrace,dfu))
|
||||||
|
$(eval $(call RULES,simtrace,trace))
|
||||||
|
$(eval $(call RULES,simtrace,cardem))
|
||||||
|
$(eval $(call RULES,qmod,dfu))
|
||||||
|
$(eval $(call RULES,qmod,cardem))
|
||||||
|
|
||||||
|
fw-clean: fw-simtrace-dfu-clean fw-simtrace-trace-clean fw-simtrace-cardem-clean fw-qmod-dfu-clean fw-qmod-cardem-clean
|
||||||
|
fw: fw-simtrace-dfu fw-simtrace-trace fw-simtrace-cardem fw-qmod-dfu fw-qmod-cardem
|
||||||
|
|
||||||
|
utils:
|
||||||
|
(cd host && \
|
||||||
|
autoreconf -fi && \
|
||||||
|
./configure --prefix=/usr --disable-werror && \
|
||||||
|
make)
|
||||||
|
|
||||||
|
clean: fw-clean
|
||||||
|
if [ -e host/Makefile ]; then \
|
||||||
|
make -C host clean; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
install:
|
||||||
|
make -C firmware install
|
||||||
|
make -C host install
|
||||||
162
contrib/flash.py
Executable file
162
contrib/flash.py
Executable file
@@ -0,0 +1,162 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
# python: 3.8.1
|
||||||
|
|
||||||
|
# library to enumerate USB devices
|
||||||
|
import usb.core
|
||||||
|
from usb.util import *
|
||||||
|
# more elegant structure
|
||||||
|
from typing import NamedTuple
|
||||||
|
# regular expressions utilities
|
||||||
|
import re
|
||||||
|
# open utilities to handle files
|
||||||
|
import os, sys
|
||||||
|
# to download the firmwares
|
||||||
|
import urllib.request
|
||||||
|
# to flash using DFU-util
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
# SIMtrace 2 device information
|
||||||
|
class Device(NamedTuple):
|
||||||
|
usb_vendor_id: int
|
||||||
|
usb_product_id: int
|
||||||
|
name: str
|
||||||
|
url: dict # 1: sniff/trace firmware, 2: card emulation firmware
|
||||||
|
|
||||||
|
# SIMtrace 2 devices definitions
|
||||||
|
DEVICE_SIMTRACE = Device(usb_vendor_id=0x1d50, usb_product_id=0x60e3, name="SIMtrace 2", url={"trace": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/simtrace-trace-dfu-latest.bin", "cardem": "https://osmocom.org/attachments/download/3868/simtrace-cardem-dfu.bin"})
|
||||||
|
DEVICE_QMOD = Device(usb_vendor_id=0x1d50, usb_product_id=0x4004, name="sysmoQMOD (Quad Modem)", url={"cardem": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/qmod-cardem-dfu-latest.bin"})
|
||||||
|
DEVICE_OWHW = Device(usb_vendor_id=0x1d50, usb_product_id=0x4001, name="OWHW", url={"cardem": "https://ftp.osmocom.org/binaries/simtrace2/firmware/latest/owhw-cardem-dfu-latest.bin"})
|
||||||
|
DEVICES = [DEVICE_SIMTRACE, DEVICE_QMOD]
|
||||||
|
|
||||||
|
# which firmware does the SIMtrace USN interface subclass correspond
|
||||||
|
FIRMWARE_SUBCLASS = {1: "trace", 2: "cardem"}
|
||||||
|
|
||||||
|
def print_help():
|
||||||
|
print("this script will flash SIMtrace 2 - based devices")
|
||||||
|
print("when no argument is provided, it will try to flash the application firmware of all SIMtrace 2 devices connected to USB with the latest version")
|
||||||
|
print("to flash a specific firmware, provide the name as argument")
|
||||||
|
print("the possible firmwares are: trace, cardem")
|
||||||
|
print("to list all devices connected to USB, provide the argument \"list\"")
|
||||||
|
|
||||||
|
# the firmware to flash
|
||||||
|
to_flash = None
|
||||||
|
|
||||||
|
# parse command line argument
|
||||||
|
if len(sys.argv) == 2:
|
||||||
|
to_flash = sys.argv[1]
|
||||||
|
if to_flash not in ["list", "trace", "cardem"] and len(sys.argv) > 1:
|
||||||
|
print_help()
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
# get all USB devices
|
||||||
|
devices = []
|
||||||
|
devices_nb = 0
|
||||||
|
updated_nb = 0
|
||||||
|
usb_devices = usb.core.find(find_all=True)
|
||||||
|
for usb_device in usb_devices:
|
||||||
|
# find SIMtrace devices
|
||||||
|
definitions = list(filter(lambda x: x.usb_vendor_id == usb_device.idVendor and x.usb_product_id == usb_device.idProduct, DEVICES))
|
||||||
|
if 1 != len(definitions):
|
||||||
|
continue
|
||||||
|
devices_nb += 1
|
||||||
|
definition = definitions[0]
|
||||||
|
serial = usb_device.serial_number or "unknown"
|
||||||
|
usb_path = str(usb_device.bus) + "-" + ".".join(map(str, usb_device.port_numbers))
|
||||||
|
print("found " + definition.name + " device (chip ID " + serial + ") at USB path " + usb_path)
|
||||||
|
# determine if we are running DFU (in most cases the bootloader, but could also be the application)
|
||||||
|
dfu_interface = None
|
||||||
|
for configuration in usb_device:
|
||||||
|
# get DFU interface descriptor
|
||||||
|
dfu_interface = dfu_interface or find_descriptor(configuration, bInterfaceClass=254, bInterfaceSubClass=1)
|
||||||
|
if (None == dfu_interface):
|
||||||
|
print("no DFU USB interface found")
|
||||||
|
continue
|
||||||
|
dfu_mode = (2 == dfu_interface.bInterfaceProtocol) # InterfaceProtocol 1 is runtime mode, 2 is DFU mode
|
||||||
|
# determine firmware type (when not in DFU mode)
|
||||||
|
firmware = None
|
||||||
|
simtrace_interface = None
|
||||||
|
for configuration in usb_device:
|
||||||
|
simtrace_interface = simtrace_interface or find_descriptor(configuration, bInterfaceClass=255)
|
||||||
|
if simtrace_interface and simtrace_interface.bInterfaceSubClass in FIRMWARE_SUBCLASS:
|
||||||
|
firmware = firmware or FIRMWARE_SUBCLASS[simtrace_interface.bInterfaceSubClass]
|
||||||
|
if dfu_mode:
|
||||||
|
firmware = 'dfu'
|
||||||
|
if firmware:
|
||||||
|
print("installed firmware: " + firmware)
|
||||||
|
else:
|
||||||
|
print("unknown installed firmware")
|
||||||
|
continue
|
||||||
|
# determine version of the application/bootloader firmware
|
||||||
|
version = None
|
||||||
|
version_interface = None
|
||||||
|
for configuration in usb_device:
|
||||||
|
# get custom interface with string
|
||||||
|
version_interface = version_interface or find_descriptor(configuration, bInterfaceClass=255, bInterfaceSubClass=255)
|
||||||
|
if version_interface and version_interface.iInterface and version_interface.iInterface > 0 and get_string(usb_device, version_interface.iInterface):
|
||||||
|
version = get_string(usb_device, version_interface.iInterface)
|
||||||
|
if not version:
|
||||||
|
# the USB serial is set (in the application) since version 0.5.1.34-e026 from 2019-08-06
|
||||||
|
# https://git.osmocom.org/simtrace2/commit/?id=e0265462d8c05ebfa133db2039c2fbe3ebbd286e
|
||||||
|
# the USB serial is set (in the bootloader) since version 0.5.1.45-ac7e from 2019-11-18
|
||||||
|
# https://git.osmocom.org/simtrace2/commit/?id=5db9402a5f346e30288db228157f71c29aefce5a
|
||||||
|
# the firmware version is set (in the application) since version 0.5.1.37-ede8 from 2019-08-13
|
||||||
|
# https://git.osmocom.org/simtrace2/commit/?id=ede87e067dadd07119f24e96261b66ac92b3af6f
|
||||||
|
# the firmware version is set (in the bootloader) since version 0.5.1.45-ac7e from 2019-11-18
|
||||||
|
# https://git.osmocom.org/simtrace2/commit/?id=5db9402a5f346e30288db228157f71c29aefce5a
|
||||||
|
if dfu_mode:
|
||||||
|
if serial:
|
||||||
|
version = "< 0.5.1.45-ac7e"
|
||||||
|
else:
|
||||||
|
versoin = "< 0.5.1.45-ac7e"
|
||||||
|
else:
|
||||||
|
if serial:
|
||||||
|
version = "< 0.5.1.37-ede8"
|
||||||
|
else:
|
||||||
|
versoin = "< 0.5.1.34-e026"
|
||||||
|
print("device firmware version: " + version)
|
||||||
|
# flash latest firmware
|
||||||
|
if to_flash == "list": # we just want to list the devices, not flash them
|
||||||
|
continue
|
||||||
|
# check the firmware exists
|
||||||
|
if firmware == "dfu" and to_flash is None:
|
||||||
|
print("device is currently in DFU mode. you need to specify which firmware to flash")
|
||||||
|
continue
|
||||||
|
to_flash = to_flash or firmware
|
||||||
|
if to_flash not in definition.url.keys():
|
||||||
|
print("no firmware image available for " + firmware + " firmware")
|
||||||
|
continue
|
||||||
|
# download firmware
|
||||||
|
try:
|
||||||
|
dl_path, header = urllib.request.urlretrieve(definition.url[to_flash])
|
||||||
|
except:
|
||||||
|
print("could not download firmware " + definition.url[to_flash])
|
||||||
|
continue
|
||||||
|
dl_file = open(dl_path, "rb")
|
||||||
|
dl_data = dl_file.read()
|
||||||
|
dl_file.close()
|
||||||
|
# compare versions
|
||||||
|
dl_version = re.search(b'firmware \d+\.\d+\.\d+\.\d+-[0-9a-fA-F]{4}', dl_data)
|
||||||
|
if dl_version is None:
|
||||||
|
print("could not get version from downloaded firmware image")
|
||||||
|
os.remove(dl_path)
|
||||||
|
continue
|
||||||
|
dl_version = dl_version.group(0).decode("utf-8").split(" ")[1]
|
||||||
|
print("latest firmware version: " + dl_version)
|
||||||
|
versions = list(map(lambda x: int(x), version.split(" ")[-1].split("-")[0].split(".")))
|
||||||
|
dl_versions = list(map(lambda x: int(x), dl_version.split("-")[0].split(".")))
|
||||||
|
dl_newer = (versions[0] < dl_versions[0] or (versions[0] == dl_versions[0] and versions[1] < dl_versions[1]) or (versions[0] == dl_versions[0] and versions[1] == dl_versions[1] and versions[2] < dl_versions[2]) or (versions[0] == dl_versions[0] and versions[1] == dl_versions[1] and versions[2] == dl_versions[2] and versions[3] < dl_versions[3]))
|
||||||
|
if not dl_newer:
|
||||||
|
print("no need to flash latest version")
|
||||||
|
os.remove(dl_path)
|
||||||
|
continue
|
||||||
|
print("flashing latest version")
|
||||||
|
dfu_result = subprocess.run(["dfu-util", "--device", hex(definition.usb_vendor_id) + ":" + hex(definition.usb_product_id), "--path", usb_path, "--cfg", "1", "--alt", "1", "--reset", "--download", dl_path])
|
||||||
|
os.remove(dl_path)
|
||||||
|
if 0 != dfu_result.returncode:
|
||||||
|
printf("flashing firmware using dfu-util failed. ensure dfu-util is installed and you have the permissions to access this USB device")
|
||||||
|
continue
|
||||||
|
updated_nb += 1
|
||||||
|
|
||||||
|
print(str(devices_nb)+ " SIMtrace 2 device(s) found")
|
||||||
|
print(str(updated_nb)+ " SIMtrace 2 device(s) updated")
|
||||||
@@ -9,6 +9,7 @@ fi
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
publish="$1"
|
||||||
base="$PWD"
|
base="$PWD"
|
||||||
deps="$base/deps"
|
deps="$base/deps"
|
||||||
inst="$deps/install"
|
inst="$deps/install"
|
||||||
@@ -20,11 +21,14 @@ mkdir "$deps" || true
|
|||||||
|
|
||||||
osmo-build-dep.sh libosmocore "" '--disable-doxygen --enable-gnutls'
|
osmo-build-dep.sh libosmocore "" '--disable-doxygen --enable-gnutls'
|
||||||
|
|
||||||
|
# verify only after building the dependency (to ensure we have most recent source of dependency)
|
||||||
|
verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]")
|
||||||
|
|
||||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||||
export LD_LIBRARY_PATH="$inst/lib"
|
export LD_LIBRARY_PATH="$inst/lib"
|
||||||
|
|
||||||
BUILDS=""
|
BUILDS=""
|
||||||
BUILDS+="simtrace/dfu simtrace/cardem " # simtrace/trace simtrace/triple_play
|
BUILDS+="simtrace/dfu simtrace/cardem simtrace/trace " # simtrace/triple_play
|
||||||
BUILDS+="qmod/dfu qmod/cardem "
|
BUILDS+="qmod/dfu qmod/cardem "
|
||||||
BUILDS+="owhw/dfu owhw/cardem "
|
BUILDS+="owhw/dfu owhw/cardem "
|
||||||
|
|
||||||
@@ -35,7 +39,6 @@ for build in $BUILDS; do
|
|||||||
echo
|
echo
|
||||||
echo "=============== $board / $app START =============="
|
echo "=============== $board / $app START =============="
|
||||||
make BOARD="$board" APP="$app"
|
make BOARD="$board" APP="$app"
|
||||||
make BOARD="$board" APP="$app" clean
|
|
||||||
echo "=============== $board / $app RES:$? =============="
|
echo "=============== $board / $app RES:$? =============="
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -50,8 +53,43 @@ make clean
|
|||||||
echo
|
echo
|
||||||
echo "=============== HOST START =============="
|
echo "=============== HOST START =============="
|
||||||
cd $TOPDIR/host
|
cd $TOPDIR/host
|
||||||
make clean
|
autoreconf --install --force
|
||||||
make
|
./configure --enable-sanitize --enable-werror
|
||||||
make clean
|
$MAKE $PARALLEL_MAKE
|
||||||
|
#$MAKE distcheck || cat-testlogs.sh
|
||||||
|
make dist
|
||||||
|
|
||||||
|
#if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
|
||||||
|
# make -C "$base/doc/manuals" publish
|
||||||
|
#fi
|
||||||
|
|
||||||
|
rm -rf $TOPDIR/firmware/bin/simtrace-cardem*
|
||||||
|
|
||||||
|
if [ "x$publish" = "x--publish" ]; then
|
||||||
|
echo
|
||||||
|
echo "=============== UPLOAD BUILD =============="
|
||||||
|
|
||||||
|
cat > "/build/known_hosts" <<EOF
|
||||||
|
[rita.osmocom.org]:48 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDgQ9HntlpWNmh953a2Gc8NysKE4orOatVT1wQkyzhARnfYUerRuwyNr1GqMyBKdSI9amYVBXJIOUFcpV81niA7zQRUs66bpIMkE9/rHxBd81SkorEPOIS84W4vm3SZtuNqa+fADcqe88Hcb0ZdTzjKILuwi19gzrQyME2knHY71EOETe9Yow5RD2hTIpB5ecNxI0LUKDq+Ii8HfBvndPBIr0BWYDugckQ3Bocf+yn/tn2/GZieFEyFpBGF/MnLbAAfUKIdeyFRX7ufaiWWz5yKAfEhtziqdAGZaXNaLG6gkpy3EixOAy6ZXuTAk3b3Y0FUmDjhOHllbPmTOcKMry9
|
||||||
|
[rita.osmocom.org]:48 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPdWn1kEousXuKsZ+qJEZTt/NSeASxCrUfNDW3LWtH+d8Ust7ZuKp/vuyG+5pe5pwpPOgFu7TjN+0lVjYJVXH54=
|
||||||
|
[rita.osmocom.org]:48 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8iivY70EiR5NiGChV39gRLjNpC8lvu1ZdHtdMw2zuX
|
||||||
|
EOF
|
||||||
|
SSH_COMMAND="ssh -o 'UserKnownHostsFile=/build/known_hosts' -p 48"
|
||||||
|
rsync --archive --verbose --compress --delete --rsh "$SSH_COMMAND" $TOPDIR/firmware/bin/*-latest.{bin,elf} binaries@rita.osmocom.org:web-files/simtrace2/firmware/latest/
|
||||||
|
rsync --archive --verbose --compress --rsh "$SSH_COMMAND" --exclude $TOPDIR/firmware/bin/*-latest.{bin,elf} $TOPDIR/firmware/bin/*-*-*-*.{bin,elf} binaries@rita.osmocom.org:web-files/simtrace2/firmware/all/
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=============== HOST CLEAN =============="
|
||||||
|
$MAKE maintainer-clean
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=============== FIRMWARE CLEAN =============="
|
||||||
|
cd $TOPDIR/firmware/
|
||||||
|
for build in $BUILDS; do
|
||||||
|
board=`echo $build | cut -d "/" -f 1`
|
||||||
|
app=`echo $build | cut -d "/" -f 2`
|
||||||
|
make BOARD="$board" APP="$app" clean
|
||||||
|
done
|
||||||
|
|
||||||
osmo-clean-workspace.sh
|
osmo-clean-workspace.sh
|
||||||
|
|||||||
17
debian/changelog
vendored
Normal file
17
debian/changelog
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
simtrace2 (0.5.2) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
* adapt to host tools in autotools
|
||||||
|
|
||||||
|
-- Harald Welte <lafore@gnumonks.org> Thu, 28 Nov 2019 00:44:57 +0100
|
||||||
|
|
||||||
|
simtrace2 (0.5.1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Backwards-compatibility with older (released, non-master) libosmocore
|
||||||
|
|
||||||
|
-- Harald Welte <lafore@gnumonks.org> Sun, 26 Aug 2018 11:50:36 +0200
|
||||||
|
|
||||||
|
simtrace2 (0.5) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Initial debian package release.
|
||||||
|
|
||||||
|
-- Harald Welte <lafore@gnumonks.org> Sun, 26 Aug 2018 10:37:19 +0200
|
||||||
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
9
|
||||||
65
debian/control
vendored
Normal file
65
debian/control
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
Source: simtrace2
|
||||||
|
Maintainer: Harald Welte <laforge@gnumonks.org>
|
||||||
|
Section: devel
|
||||||
|
Priority: optional
|
||||||
|
Build-Depends: debhelper (>= 9),
|
||||||
|
autotools-dev,
|
||||||
|
autoconf,
|
||||||
|
automake,
|
||||||
|
libtool,
|
||||||
|
pkg-config,
|
||||||
|
git,
|
||||||
|
dh-autoreconf,
|
||||||
|
libosmocore-dev,
|
||||||
|
libpcsclite-dev,
|
||||||
|
libnewlib-arm-none-eabi,
|
||||||
|
libusb-1.0-0-dev,
|
||||||
|
gcc-arm-none-eabi
|
||||||
|
Standards-Version: 3.9.8
|
||||||
|
Vcs-Git: git://git.osmocom.org/simtrace2.git
|
||||||
|
Vcs-Browser: http://git.osmocom.org/simtrace2/
|
||||||
|
Homepage: http://osmocom.org/projects/simtrace2/wiki
|
||||||
|
|
||||||
|
Package: simtrace2-firmware
|
||||||
|
Section: devel
|
||||||
|
Architecture: all
|
||||||
|
Recommends: dfu-util
|
||||||
|
Description: Firmware for SAM3 based SIMtrace2 USB Devices.
|
||||||
|
Open Source firmware for the Cortex-M3 microcontroller in the
|
||||||
|
"Osmocom SIMtrace2" USB-attached peripheral device. Will only work in
|
||||||
|
SAM3S-based SIMtrace2, not in its SAM7S-based predecessor SIMtrace!
|
||||||
|
|
||||||
|
Package: simtrace2-utils
|
||||||
|
Section: devel
|
||||||
|
Architecture: any
|
||||||
|
Multi-Arch: same
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends}, libosmo-simtrace2-0
|
||||||
|
Recommends: simtrace2-firmware
|
||||||
|
Description: Host utilities to communicate with SIMtrace2 USB Devices.
|
||||||
|
|
||||||
|
Package: libosmo-simtrace2-0
|
||||||
|
Section: libs
|
||||||
|
Architecture: any
|
||||||
|
Multi-Arch: same
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||||
|
Description: Osmocom SIMtrace2 library
|
||||||
|
This library contains core "driver" functionality to interface with the
|
||||||
|
Osmocom SIMtrace2 (and compatible) USB device firmware. It enables
|
||||||
|
applications to implement SIM card / smart card tracing as well as
|
||||||
|
SIM / smart card emulation functions.
|
||||||
|
|
||||||
|
Package: libosmo-simtrace2-dev
|
||||||
|
Section: libdevel
|
||||||
|
Architecture: any
|
||||||
|
Multi-Arch: same
|
||||||
|
Depends: libosmo-simtrace2-0, ${misc:Depends}
|
||||||
|
Description: Development headers for Osmocom SIMtrace2 library
|
||||||
|
This library contains core "driver" functionality to interface with the
|
||||||
|
Osmocom SIMtrace2 (and compatible) USB device firmware. It enables
|
||||||
|
applications to implement SIM card / smart card tracing as well as
|
||||||
|
SIM / smart card emulation functions.
|
||||||
|
.
|
||||||
|
The header files provided by this package may be used to develop
|
||||||
|
with any of the libosmocore libraries.
|
||||||
|
.
|
||||||
|
Also static libraries are installed with this package.
|
||||||
1
debian/libosmo-simtrace2-0.install
vendored
Normal file
1
debian/libosmo-simtrace2-0.install
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
usr/lib/libosmo-simtrace2*.so.*
|
||||||
5
debian/libosmo-simtrace2-dev.install
vendored
Normal file
5
debian/libosmo-simtrace2-dev.install
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
usr/include/*
|
||||||
|
usr/lib/lib*.a
|
||||||
|
usr/lib/lib*.so
|
||||||
|
usr/lib/lib*.la
|
||||||
|
usr/lib/pkgconfig/*
|
||||||
19
debian/rules
vendored
Executable file
19
debian/rules
vendored
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
#export DH_VERBOSE=1
|
||||||
|
|
||||||
|
DEBIAN := $(shell dpkg-parsechangelog | grep ^Version: | cut -d' ' -f2)
|
||||||
|
DEBVERS := $(shell echo '$(DEBIAN)' | cut -d- -f1)
|
||||||
|
VERSION := $(shell echo '$(DEBVERS)' | sed -e 's/[+-].*//' -e 's/~//g')
|
||||||
|
|
||||||
|
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||||
|
|
||||||
|
export DEB_LDFLAGS_MAINT_STRIP = -Wl,-Bsymbolic-functions
|
||||||
|
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@
|
||||||
|
|
||||||
|
override_dh_autoreconf:
|
||||||
|
cd host && dh_autoreconf
|
||||||
1
debian/simtrace2-firmware.install
vendored
Normal file
1
debian/simtrace2-firmware.install
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
usr/share/simtrace2/*.bin
|
||||||
1
debian/simtrace2-utils.install
vendored
Normal file
1
debian/simtrace2-utils.install
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
usr/bin/simtrace2-*
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
# Makefile for compiling the Getting Started with SAM3S Microcontrollers project
|
# Makefile for compiling the Getting Started with SAM3S Microcontrollers project
|
||||||
|
|
||||||
|
GIT_VERSION=$(shell $(TOP)/git-version-gen $(TOP)/.tarvers)
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# User-modifiable options
|
# User-modifiable options
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@@ -36,14 +37,16 @@
|
|||||||
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
||||||
CHIP ?= sam3s4
|
CHIP ?= sam3s4
|
||||||
BOARD ?= qmod
|
BOARD ?= qmod
|
||||||
|
|
||||||
# Defines which are the available memory targets for the SAM3S-EK board.
|
|
||||||
MEMORIES ?= flash dfu
|
|
||||||
|
|
||||||
# Output file basename
|
|
||||||
APP ?= dfu
|
APP ?= dfu
|
||||||
|
|
||||||
# Output directories
|
# Defines which are the available memory targets for the SAM3S-EK board.
|
||||||
|
ifeq ($(APP), dfu)
|
||||||
|
MEMORIES ?= flash dfu
|
||||||
|
else
|
||||||
|
MEMORIES ?= dfu
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Output directories and filename
|
||||||
OUTPUT = $(BOARD)-$(APP)
|
OUTPUT = $(BOARD)-$(APP)
|
||||||
BIN = bin
|
BIN = bin
|
||||||
OBJ = obj/$(BOARD)
|
OBJ = obj/$(BOARD)
|
||||||
@@ -73,7 +76,6 @@ GDB = $(CROSS_COMPILE)gdb
|
|||||||
NM = $(CROSS_COMPILE)nm
|
NM = $(CROSS_COMPILE)nm
|
||||||
|
|
||||||
TOP=..
|
TOP=..
|
||||||
GIT_VERSION=$(shell $(TOP)/git-version-gen $(TOP)/.tarvers)
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# Files
|
# Files
|
||||||
@@ -97,10 +99,11 @@ C_LIBCHIP = $(notdir $(wildcard $(AT91LIB)/libchip_sam3s/source/*.c) $(wildcard
|
|||||||
C_LIBUSB = USBDescriptors.c USBRequests.c USBD.c USBDCallbacks.c USBDDriver.c USBDDriverCallbacks.c
|
C_LIBUSB = USBDescriptors.c USBRequests.c USBD.c USBDCallbacks.c USBDDriver.c USBDDriverCallbacks.c
|
||||||
C_LIBUSB_RT = dfu.c dfu_runtime.c
|
C_LIBUSB_RT = dfu.c dfu_runtime.c
|
||||||
C_LIBUSB_DFU = dfu.c dfu_desc.c dfu_driver.c
|
C_LIBUSB_DFU = dfu.c dfu_desc.c dfu_driver.c
|
||||||
C_LIBCOMMON = string.c stdio.c fputs.c usb_buf.c ringbuffer.c pseudo_talloc.c host_communication.c
|
C_LIBCOMMON = string.c stdio.c fputs.c usb_buf.c ringbuffer.c pseudo_talloc.c host_communication.c \
|
||||||
|
main_common.c
|
||||||
|
|
||||||
C_BOARD = $(notdir $(wildcard libboard/common/source/*.c))
|
C_BOARD = $(notdir $(wildcard libboard/common/source/*.c))
|
||||||
C_BOARD += $(notdir $(wildcard libboard/$(BOARD)/source/*.c))
|
C_BOARD += $(notdir $(wildcard libboard/$(BOARD)/source/*.c))
|
||||||
|
|
||||||
C_APPLEVEL = $(notdir $(wildcard apps/$(APP)/*.c))
|
C_APPLEVEL = $(notdir $(wildcard apps/$(APP)/*.c))
|
||||||
|
|
||||||
@@ -120,15 +123,15 @@ C_OBJECTS = $(C_FILES:%.c=%.o)
|
|||||||
# TRACE_LEVEL_NO_TRACE 0
|
# TRACE_LEVEL_NO_TRACE 0
|
||||||
TRACE_LEVEL ?= 4
|
TRACE_LEVEL ?= 4
|
||||||
|
|
||||||
DEBUG_PHONE_SNIFF?=0
|
# allow asserting the peer SAM3S ERASE signal to completely erase the flash
|
||||||
|
# only applicable for qmod board
|
||||||
|
ALLOW_PEER_ERASE?=0
|
||||||
|
|
||||||
#CFLAGS+=-DUSB_NO_DEBUG=1
|
#CFLAGS+=-DUSB_NO_DEBUG=1
|
||||||
|
|
||||||
# Optimization level, put in comment for debugging
|
# Optimization level, put in comment for debugging
|
||||||
OPTIMIZATION ?= -Os
|
OPTIMIZATION ?= -Os
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Flags
|
# Flags
|
||||||
INCLUDES_USB = -I$(AT91LIB)/usb/include -I$(AT91LIB)
|
INCLUDES_USB = -I$(AT91LIB)/usb/include -I$(AT91LIB)
|
||||||
|
|
||||||
@@ -141,13 +144,12 @@ INCLUDES += -Ilibosmocore/include
|
|||||||
INCLUDES += -Isrc_simtrace -Iinclude
|
INCLUDES += -Isrc_simtrace -Iinclude
|
||||||
INCLUDES += -Iapps/$(APP)
|
INCLUDES += -Iapps/$(APP)
|
||||||
|
|
||||||
CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wimplicit-int #-Wformat=2
|
CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wimplicit-int -Wformat=2
|
||||||
CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses
|
CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses
|
||||||
CFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs #-Wunused
|
CFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs #-Wunused
|
||||||
CFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal #-Wundef
|
CFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal #-Wundef
|
||||||
CFLAGS += -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings
|
CFLAGS += -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings
|
||||||
CFLAGS += -Waggregate-return #-Wsign-compare
|
CFLAGS += -Waggregate-return #-Wsign-compare
|
||||||
CFLAGS += -Wformat=0
|
|
||||||
CFLAGS += -Wmissing-format-attribute -Wno-deprecated-declarations
|
CFLAGS += -Wmissing-format-attribute -Wno-deprecated-declarations
|
||||||
CFLAGS += #-Wpacked
|
CFLAGS += #-Wpacked
|
||||||
CFLAGS += -Wredundant-decls -Wnested-externs #-Winline -Wlong-long
|
CFLAGS += -Wredundant-decls -Wnested-externs #-Winline -Wlong-long
|
||||||
@@ -164,16 +166,15 @@ CFLAGS += -Wno-suggest-attribute=noreturn
|
|||||||
#CFLAGS += -Wa,-a,-ad
|
#CFLAGS += -Wa,-a,-ad
|
||||||
CFLAGS += -D__ARM
|
CFLAGS += -D__ARM
|
||||||
CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb # -mfix-cortex-m3-ldrd
|
CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb # -mfix-cortex-m3-ldrd
|
||||||
CFLAGS += -ffunction-sections -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL) -DDEBUG_PHONE_SNIFF=$(DEBUG_PHONE_SNIFF)
|
CFLAGS += -ffunction-sections -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL) -DALLOW_PEER_ERASE=$(ALLOW_PEER_ERASE)
|
||||||
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
|
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
|
||||||
CFLAGS += -DBOARD=\"$(BOARD)\" -DBOARD_$(BOARD)
|
CFLAGS += -DBOARD=\"$(BOARD)\" -DBOARD_$(BOARD)
|
||||||
CFLAGS += -DAPPLICATION=\"$(APP)\" -DAPPLICATION_$(APP)
|
CFLAGS += -DAPPLICATION=\"$(APP)\" -DAPPLICATION_$(APP)
|
||||||
ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
|
ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
|
||||||
LDFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=ResetException -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols $(LIB)
|
LDFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=ResetException -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--print-memory-usage $(LIB)
|
||||||
#LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats
|
#LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats
|
||||||
|
|
||||||
|
# Append BIN directories to output filename
|
||||||
# Append OBJ and BIN directories to output filename
|
|
||||||
OUTPUT := $(BIN)/$(OUTPUT)
|
OUTPUT := $(BIN)/$(OUTPUT)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@@ -197,7 +198,11 @@ $(BIN) $(OBJ):
|
|||||||
usbstring/usbstring: usbstring/usbstring.c
|
usbstring/usbstring: usbstring/usbstring.c
|
||||||
gcc $^ -o $@
|
gcc $^ -o $@
|
||||||
|
|
||||||
apps/$(APP)/usb_strings_generated.h: apps/$(APP)/usb_strings.txt usbstring/usbstring
|
.PHONY: apps/$(APP)/usb_strings.txt.patched
|
||||||
|
apps/$(APP)/usb_strings.txt.patched: apps/$(APP)/usb_strings.txt
|
||||||
|
sed "s/PRODUCT_STRING/$(shell cat libboard/$(BOARD)/product_string.txt)/" $< > $@
|
||||||
|
|
||||||
|
apps/$(APP)/usb_strings_generated.h: apps/$(APP)/usb_strings.txt.patched usbstring/usbstring
|
||||||
cat $< | usbstring/usbstring > $@
|
cat $< | usbstring/usbstring > $@
|
||||||
|
|
||||||
define RULES
|
define RULES
|
||||||
@@ -206,8 +211,12 @@ ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
|
|||||||
|
|
||||||
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
|
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
|
||||||
@$(CC) $(LDFLAGS) $(LD_OPTIONAL) -T"libboard/common/resources/$(CHIP)/$$@.ld" -Wl,-Map,$(OUTPUT)-$$@.map -o $(OUTPUT)-$$@.elf $$^ $(LIBS)
|
@$(CC) $(LDFLAGS) $(LD_OPTIONAL) -T"libboard/common/resources/$(CHIP)/$$@.ld" -Wl,-Map,$(OUTPUT)-$$@.map -o $(OUTPUT)-$$@.elf $$^ $(LIBS)
|
||||||
|
cp $(OUTPUT)-$$@.elf $(OUTPUT)-$$@-$(GIT_VERSION).elf
|
||||||
|
cp $(OUTPUT)-$$@.elf $(OUTPUT)-$$@-latest.elf
|
||||||
@$(NM) $(OUTPUT)-$$@.elf >$(OUTPUT)-$$@.elf.txt
|
@$(NM) $(OUTPUT)-$$@.elf >$(OUTPUT)-$$@.elf.txt
|
||||||
@$(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
|
@$(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
|
||||||
|
cp $(OUTPUT)-$$@.bin $(OUTPUT)-$$@-$(GIT_VERSION).bin
|
||||||
|
cp $(OUTPUT)-$$@.bin $(OUTPUT)-$$@-latest.bin
|
||||||
@$(SIZE) $$^ $(OUTPUT)-$$@.elf
|
@$(SIZE) $$^ $(OUTPUT)-$$@.elf
|
||||||
|
|
||||||
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
|
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
|
||||||
@@ -229,8 +238,13 @@ program:
|
|||||||
|
|
||||||
SERIAL ?= /dev/ttyUSB0
|
SERIAL ?= /dev/ttyUSB0
|
||||||
log:
|
log:
|
||||||
stty -F $(SERIAL) 115200
|
stty -F $(SERIAL) 921600
|
||||||
lsof $(SERIAL) && echo "log is already opened" || ( sed -u "s/\r//" $(SERIAL) | ts )
|
lsof $(SERIAL) && echo "log is already opened" || ( sed -u "s/\r//" $(SERIAL) | ts )
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
-rm -f apps/$(APP)/usb_strings.txt.patched
|
||||||
-rm -fR $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf $(BIN)/*.elf.txt $(BIN)/*.map $(BIN)/*.lst `find . -name \*.p`
|
-rm -fR $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf $(BIN)/*.elf.txt $(BIN)/*.map $(BIN)/*.lst `find . -name \*.p`
|
||||||
|
|
||||||
|
install:
|
||||||
|
mkdir -p $(DESTDIR)/usr/share/simtrace2
|
||||||
|
cp $(BIN)/*.bin $(BIN)/*.elf $(BIN)/*.elf.txt $(BIN)/*.map $(DESTDIR)/usr/share/simtrace2
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ Current boards supported are:
|
|||||||
* `simtrace`: The good old Osmocom SIMtrace PCB with SAM3 instead of SAM7, open hardware.
|
* `simtrace`: The good old Osmocom SIMtrace PCB with SAM3 instead of SAM7, open hardware.
|
||||||
* `qmod`: A sysmocom-proprietary quad mPCIe carrier board, publicly available
|
* `qmod`: A sysmocom-proprietary quad mPCIe carrier board, publicly available
|
||||||
* `owhw`: An undisclosed sysmocom-internal board, not publicly available
|
* `owhw`: An undisclosed sysmocom-internal board, not publicly available
|
||||||
|
* `octsimtest`: A sysmocom-proprietary production testing board, not publicly available
|
||||||
|
|
||||||
= Firmware
|
= Firmware
|
||||||
|
|
||||||
@@ -51,6 +52,7 @@ Current applications supported are:
|
|||||||
* `cardem`: To provide remote SIM operation capabilities.
|
* `cardem`: To provide remote SIM operation capabilities.
|
||||||
* `trace`: To monitor the communication between a SIM card and a phone (corresponds to the functionality provide by the first SIMtrace)
|
* `trace`: To monitor the communication between a SIM card and a phone (corresponds to the functionality provide by the first SIMtrace)
|
||||||
* `triple_play`: To support the three previous functionalities, using USB configurations.
|
* `triple_play`: To support the three previous functionalities, using USB configurations.
|
||||||
|
* `gpio_test`: internal test code
|
||||||
|
|
||||||
== Memories
|
== Memories
|
||||||
|
|
||||||
@@ -76,6 +78,10 @@ $ make TRACE_LEVEL=4
|
|||||||
```
|
```
|
||||||
Accepted values: 0 (NO_TRACE) to 5 (DEBUG)
|
Accepted values: 0 (NO_TRACE) to 5 (DEBUG)
|
||||||
|
|
||||||
|
The qmod specific option `ALLOW_PEER_ERASE` controls if the UART debug command to assert the peer SAM3S ERASE line is present in the code.
|
||||||
|
Per default this is set to 0 to prevent accidentally erasing all firmware, including the DFU bootloader, which would then need to be flashed using SAM-BA or JTAG/SWD.
|
||||||
|
Setting `ALLOW_PEER_ERASE` to 1 enables back the debug command and should be used only for debugging or development purposes.
|
||||||
|
|
||||||
= Flashing
|
= Flashing
|
||||||
|
|
||||||
To flash a firmware image follow the instructions provided in the [wiki](https://projects.osmocom.org/projects/simtrace2/wiki/).
|
To flash a firmware image follow the instructions provided in the [wiki](https://projects.osmocom.org/projects/simtrace2/wiki/).
|
||||||
|
|||||||
@@ -1,4 +1,22 @@
|
|||||||
// FIXME: Copyright license here
|
/* SIMtrace 2 firmware card emulation application
|
||||||
|
*
|
||||||
|
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* (C) 2018-2019, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Headers
|
* Headers
|
||||||
*------------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------------*/
|
||||||
@@ -6,10 +24,9 @@
|
|||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "simtrace.h"
|
#include "simtrace.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "main_common.h"
|
||||||
#include <osmocom/core/timer.h>
|
#include <osmocom/core/timer.h>
|
||||||
|
|
||||||
unsigned int g_unique_id[4];
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Internal variables
|
* Internal variables
|
||||||
*------------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------------*/
|
||||||
@@ -22,7 +39,7 @@ typedef struct {
|
|||||||
void (*exit) (void);
|
void (*exit) (void);
|
||||||
/* main loop content for given configuration */
|
/* main loop content for given configuration */
|
||||||
void (*run) (void);
|
void (*run) (void);
|
||||||
/* Interrupt handler for USART1 */
|
/* Interrupt handler for USART0 */
|
||||||
void (*usart0_irq) (void);
|
void (*usart0_irq) (void);
|
||||||
/* Interrupt handler for USART1 */
|
/* Interrupt handler for USART1 */
|
||||||
void (*usart1_irq) (void);
|
void (*usart1_irq) (void);
|
||||||
@@ -36,6 +53,8 @@ static const conf_func config_func_ptrs[] = {
|
|||||||
.init = Sniffer_init,
|
.init = Sniffer_init,
|
||||||
.exit = Sniffer_exit,
|
.exit = Sniffer_exit,
|
||||||
.run = Sniffer_run,
|
.run = Sniffer_run,
|
||||||
|
.usart0_irq = Sniffer_usart0_irq,
|
||||||
|
.usart1_irq = Sniffer_usart1_irq,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CCID
|
#ifdef HAVE_CCID
|
||||||
@@ -84,7 +103,11 @@ static volatile enum confNum simtrace_config = CFG_NUM_CCID;
|
|||||||
void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
|
void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
|
||||||
{
|
{
|
||||||
TRACE_INFO_WP("cfgChanged%d ", cfgnum);
|
TRACE_INFO_WP("cfgChanged%d ", cfgnum);
|
||||||
simtrace_config = cfgnum;
|
if (cfgnum < ARRAY_SIZE(config_func_ptrs)) {
|
||||||
|
simtrace_config = cfgnum;
|
||||||
|
} else {
|
||||||
|
TRACE_ERROR("trying to set out of bounds config %u\r\n", cfgnum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void USART1_IrqHandler(void)
|
void USART1_IrqHandler(void)
|
||||||
@@ -108,7 +131,8 @@ static void check_exec_dbg_cmd(void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ch = UART_GetChar();
|
ch = UART_GetChar();
|
||||||
|
/* We must echo the character to make python fdexpect happy, which we use in factory testing */
|
||||||
|
fputc(ch, stdout);
|
||||||
board_exec_dbg_cmd(ch);
|
board_exec_dbg_cmd(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,25 +149,13 @@ extern int main(void)
|
|||||||
led_init();
|
led_init();
|
||||||
led_blink(LED_RED, BLINK_3O_5F);
|
led_blink(LED_RED, BLINK_3O_5F);
|
||||||
|
|
||||||
/* Enable watchdog for 500ms, with no window */
|
/* Enable watchdog for 2000ms, with no window */
|
||||||
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
|
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
|
||||||
(WDT_GetPeriod(500) << 16) | WDT_GetPeriod(500));
|
(WDT_GetPeriod(2000) << 16) | WDT_GetPeriod(2000));
|
||||||
|
|
||||||
PIO_InitializeInterrupts(0);
|
PIO_InitializeInterrupts(0);
|
||||||
|
|
||||||
EEFC_ReadUniqueID(g_unique_id);
|
print_banner();
|
||||||
|
|
||||||
printf("\n\r\n\r"
|
|
||||||
"=============================================================================\n\r"
|
|
||||||
"SIMtrace2 firmware " GIT_VERSION " (C) 2010-2016 by Harald Welte\n\r"
|
|
||||||
"=============================================================================\n\r");
|
|
||||||
|
|
||||||
TRACE_INFO("Chip ID: 0x%08x (Ext 0x%08x)\n\r", CHIPID->CHIPID_CIDR, CHIPID->CHIPID_EXID);
|
|
||||||
TRACE_INFO("Serial Nr. %08x-%08x-%08x-%08x\n\r",
|
|
||||||
g_unique_id[0], g_unique_id[1],
|
|
||||||
g_unique_id[2], g_unique_id[3]);
|
|
||||||
TRACE_INFO("Reset Cause: 0x%x\n\r", (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos);
|
|
||||||
|
|
||||||
board_main_top();
|
board_main_top();
|
||||||
|
|
||||||
TRACE_INFO("USB init...\n\r");
|
TRACE_INFO("USB init...\n\r");
|
||||||
@@ -164,14 +176,15 @@ extern int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TRACE_INFO("calling configure of all configurations...\n\r");
|
TRACE_INFO("calling configure of all configurations...\n\r");
|
||||||
for (i = 1; i < sizeof(config_func_ptrs) / sizeof(config_func_ptrs[0]);
|
for (i = 1; i < ARRAY_SIZE(config_func_ptrs); i++) {
|
||||||
++i) {
|
|
||||||
if (config_func_ptrs[i].configure)
|
if (config_func_ptrs[i].configure)
|
||||||
config_func_ptrs[i].configure();
|
config_func_ptrs[i].configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_INFO("calling init of config %u...\n\r", simtrace_config);
|
TRACE_INFO("calling init of config %u...\n\r", simtrace_config);
|
||||||
config_func_ptrs[simtrace_config].init();
|
if (config_func_ptrs[simtrace_config].init) {
|
||||||
|
config_func_ptrs[simtrace_config].init();
|
||||||
|
}
|
||||||
last_simtrace_config = simtrace_config;
|
last_simtrace_config = simtrace_config;
|
||||||
|
|
||||||
TRACE_INFO("entering main loop...\n\r");
|
TRACE_INFO("entering main loop...\n\r");
|
||||||
@@ -199,11 +212,18 @@ extern int main(void)
|
|||||||
if (last_simtrace_config != simtrace_config) {
|
if (last_simtrace_config != simtrace_config) {
|
||||||
TRACE_INFO("USB config chg %u -> %u\n\r",
|
TRACE_INFO("USB config chg %u -> %u\n\r",
|
||||||
last_simtrace_config, simtrace_config);
|
last_simtrace_config, simtrace_config);
|
||||||
config_func_ptrs[last_simtrace_config].exit();
|
if (config_func_ptrs[last_simtrace_config].exit) {
|
||||||
config_func_ptrs[simtrace_config].init();
|
config_func_ptrs[last_simtrace_config].exit();
|
||||||
|
}
|
||||||
|
if (config_func_ptrs[simtrace_config].init) {
|
||||||
|
config_func_ptrs[simtrace_config].init();
|
||||||
|
}
|
||||||
last_simtrace_config = simtrace_config;
|
last_simtrace_config = simtrace_config;
|
||||||
} else {
|
} else {
|
||||||
config_func_ptrs[simtrace_config].run();
|
//FIXME: usb_proces() for every interface in this configuration?
|
||||||
|
if (config_func_ptrs[simtrace_config].run) {
|
||||||
|
config_func_ptrs[simtrace_config].run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
sysmocom - s.f.m.c. GmbH
|
sysmocom - s.f.m.c. GmbH
|
||||||
SIMtrace 2 compatible device
|
PRODUCT_STRING
|
||||||
SIMtrace Sniffer
|
SIMtrace Sniffer
|
||||||
SIMtrace CCID
|
SIMtrace CCID
|
||||||
SIMtrace Phone
|
SIMtrace Card Emulation
|
||||||
SIMtrace MITM
|
SIMtrace MITM
|
||||||
CardEmulator Modem 1
|
CardEmulator Modem 1
|
||||||
CardEmulator Modem 2
|
CardEmulator Modem 2
|
||||||
|
|||||||
@@ -1,27 +1,68 @@
|
|||||||
|
/* SIMtrace 2 firmware USB DFU bootloader
|
||||||
|
*
|
||||||
|
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* (C) 2018-2019 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 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 "board.h"
|
#include "board.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "usb/device/dfu/dfu.h"
|
#include "usb/device/dfu/dfu.h"
|
||||||
#include "usb/common/dfu/usb_dfu.h"
|
#include "usb/common/dfu/usb_dfu.h"
|
||||||
#include "manifest.h"
|
#include "manifest.h"
|
||||||
|
#include "USBD_HAL.h"
|
||||||
|
|
||||||
#include <osmocom/core/timer.h>
|
#include <osmocom/core/timer.h>
|
||||||
|
|
||||||
|
/* USB alternate interface index used to identify which partition to flash */
|
||||||
|
/** USB alternate interface index indicating RAM partition */
|
||||||
#define ALTIF_RAM 0
|
#define ALTIF_RAM 0
|
||||||
|
/** USB alternate interface index indicating flash partition */
|
||||||
|
#if defined(ENVIRONMENT_flash)
|
||||||
#define ALTIF_FLASH 1
|
#define ALTIF_FLASH 1
|
||||||
|
#elif defined(ENVIRONMENT_dfu)
|
||||||
|
#define ALTIF_FLASH 2
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned int g_unique_id[4];
|
unsigned int g_unique_id[4];
|
||||||
/* remember if the watchdog has been configured in the main loop so we can kick it in the ISR */
|
/* remember if the watchdog has been configured in the main loop so we can kick it in the ISR */
|
||||||
static bool watchdog_configured = false;
|
static bool watchdog_configured = false;
|
||||||
|
|
||||||
|
/* There is not enough space in the 16 KiB DFU bootloader to include led.h functions */
|
||||||
|
#ifdef PINS_LEDS
|
||||||
|
/** LED pin configurations */
|
||||||
|
static const Pin pinsLeds[] = { PINS_LEDS } ;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
* Callbacks
|
* Callbacks
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define RAM_ADDR(offset) (IRAM_ADDR + BOARD_DFU_RAM_SIZE + offset)
|
#define RAM_ADDR(offset) (IRAM_ADDR + BOARD_DFU_RAM_SIZE + offset)
|
||||||
|
#if defined(ENVIRONMENT_flash)
|
||||||
#define FLASH_ADDR(offset) (IFLASH_ADDR + BOARD_DFU_BOOT_SIZE + offset)
|
#define FLASH_ADDR(offset) (IFLASH_ADDR + BOARD_DFU_BOOT_SIZE + offset)
|
||||||
|
#elif defined(ENVIRONMENT_dfu)
|
||||||
|
#define FLASH_ADDR(offset) (IFLASH_ADDR + offset)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define IFLASH_END ((uint8_t *)IFLASH_ADDR + IFLASH_SIZE)
|
#define IRAM_END ((uint8_t *)IRAM_ADDR + IRAM_SIZE)
|
||||||
#define IRAM_END ((uint8_t *)IRAM_ADDR + IRAM_SIZE)
|
#if defined(ENVIRONMENT_flash)
|
||||||
|
#define IFLASH_END ((uint8_t *)IFLASH_ADDR + IFLASH_SIZE)
|
||||||
|
#elif defined(ENVIRONMENT_dfu)
|
||||||
|
#define IFLASH_END ((uint8_t *)IFLASH_ADDR + BOARD_DFU_BOOT_SIZE)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* incoming call-back: Host has transferred 'len' bytes (stored at
|
/* incoming call-back: Host has transferred 'len' bytes (stored at
|
||||||
* 'data'), which we shall write to 'offset' into the partition
|
* 'data'), which we shall write to 'offset' into the partition
|
||||||
@@ -40,7 +81,15 @@ int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
|
|||||||
WDT_Restart(WDT);
|
WDT_Restart(WDT);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("dnload(altif=%u, offset=%u, len=%u)\n\r", altif, offset, len);
|
#if TRACE_LEVEL >= TRACE_LEVEL_INFO
|
||||||
|
TRACE_INFO("dnload(altif=%u, offset=%u, len=%u)\n\r", altif, offset, len);
|
||||||
|
#else
|
||||||
|
printf("DL off=%u\n\r", offset);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PINS_LEDS
|
||||||
|
PIO_Clear(&pinsLeds[LED_NUM_RED]);
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (altif) {
|
switch (altif) {
|
||||||
case ALTIF_RAM:
|
case ALTIF_RAM:
|
||||||
@@ -48,47 +97,56 @@ int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
|
|||||||
if (addr < IRAM_ADDR || addr + len >= IRAM_ADDR + IRAM_SIZE || addr + len >= stack_addr) {
|
if (addr < IRAM_ADDR || addr + len >= IRAM_ADDR + IRAM_SIZE || addr + len >= stack_addr) {
|
||||||
g_dfu->state = DFU_STATE_dfuERROR;
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
g_dfu->status = DFU_STATUS_errADDRESS;
|
g_dfu->status = DFU_STATUS_errADDRESS;
|
||||||
return DFU_RET_STALL;
|
rc = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
memcpy((void *)addr, data, len);
|
memcpy((void *)addr, data, len);
|
||||||
return DFU_RET_ZLP;
|
rc = DFU_RET_ZLP;
|
||||||
|
break;
|
||||||
case ALTIF_FLASH:
|
case ALTIF_FLASH:
|
||||||
addr = FLASH_ADDR(offset);
|
addr = FLASH_ADDR(offset);
|
||||||
|
#if defined(ENVIRONMENT_flash)
|
||||||
if (addr < IFLASH_ADDR || addr + len >= IFLASH_ADDR + IFLASH_SIZE) {
|
if (addr < IFLASH_ADDR || addr + len >= IFLASH_ADDR + IFLASH_SIZE) {
|
||||||
|
#elif defined(ENVIRONMENT_dfu)
|
||||||
|
if (addr < IFLASH_ADDR || addr + len >= IFLASH_ADDR + BOARD_DFU_BOOT_SIZE) {
|
||||||
|
#endif
|
||||||
g_dfu->state = DFU_STATE_dfuERROR;
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
g_dfu->status = DFU_STATUS_errADDRESS;
|
g_dfu->status = DFU_STATUS_errADDRESS;
|
||||||
return DFU_RET_STALL;
|
rc = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
rc = FLASHD_Unlock(addr, addr + len, 0, 0);
|
rc = FLASHD_Unlock(addr, addr + len, 0, 0);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
TRACE_ERROR("DFU download flash unlock failed\n\r");
|
TRACE_ERROR("DFU download flash unlock failed\n\r");
|
||||||
/* FIXME: set error codes */
|
rc = DFU_RET_STALL;
|
||||||
return DFU_RET_STALL;
|
break;
|
||||||
}
|
}
|
||||||
rc = FLASHD_Write(addr, data, len);
|
rc = FLASHD_Write(addr, data, len);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
TRACE_ERROR("DFU download flash erase failed\n\r");
|
TRACE_ERROR("DFU download flash erase failed\n\r");
|
||||||
/* FIXME: set error codes */
|
rc = DFU_RET_STALL;
|
||||||
return DFU_RET_STALL;
|
break;
|
||||||
}
|
}
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (((uint8_t*)addr)[i]!=data[i]) {
|
if (((uint8_t*)addr)[i]!=data[i]) {
|
||||||
TRACE_ERROR("DFU download flash data written not correct\n\r");
|
TRACE_ERROR("DFU download flash data written not correct\n\r");
|
||||||
return DFU_RET_STALL;
|
rc = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = FLASHD_Lock(addr, addr + len, 0, 0);
|
rc = DFU_RET_ZLP;
|
||||||
if (rc != 0) {
|
break;
|
||||||
TRACE_ERROR("DFU download flash lock failed\n\r");
|
|
||||||
/* FIXME: set error codes */
|
|
||||||
return DFU_RET_STALL;
|
|
||||||
}
|
|
||||||
return DFU_RET_ZLP;
|
|
||||||
default:
|
default:
|
||||||
/* FIXME: set error codes */
|
|
||||||
TRACE_ERROR("DFU download for unknown AltIf %d\n\r", altif);
|
TRACE_ERROR("DFU download for unknown AltIf %d\n\r", altif);
|
||||||
return DFU_RET_STALL;
|
rc = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PINS_LEDS
|
||||||
|
PIO_Set(&pinsLeds[LED_NUM_RED]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* incoming call-back: Host has requested to read back 'req_len' bytes
|
/* incoming call-back: Host has requested to read back 'req_len' bytes
|
||||||
@@ -144,22 +202,30 @@ WEAK int board_override_enter_dfu(void)
|
|||||||
int USBDFU_OverrideEnterDFU(void)
|
int USBDFU_OverrideEnterDFU(void)
|
||||||
{
|
{
|
||||||
uint32_t *app_part = (uint32_t *)FLASH_ADDR(0);
|
uint32_t *app_part = (uint32_t *)FLASH_ADDR(0);
|
||||||
|
/* at the first call we are before the text segment has been relocated,
|
||||||
|
* so g_dfu is not initialized yet */
|
||||||
|
g_dfu = &_g_dfu;
|
||||||
|
if (USB_DFU_MAGIC == g_dfu->magic) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the loopback jumper is set, we enter DFU mode */
|
/* If the loopback jumper is set, we enter DFU mode */
|
||||||
if (board_override_enter_dfu())
|
if (board_override_enter_dfu()) {
|
||||||
return 1;
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
/* if the first word of the application partition doesn't look
|
/* if the first word of the application partition doesn't look
|
||||||
* like a stack pointer (i.e. point to RAM), enter DFU mode */
|
* like a stack pointer (i.e. point to RAM), enter DFU mode */
|
||||||
if ((app_part[0] < IRAM_ADDR) ||
|
if ((app_part[0] < IRAM_ADDR) || ((uint8_t *)app_part[0] > IRAM_END)) {
|
||||||
((uint8_t *)app_part[0] > IRAM_END))
|
return 3;
|
||||||
return 1;
|
}
|
||||||
|
|
||||||
/* if the second word of the application partition doesn't look
|
/* if the second word of the application partition doesn't look
|
||||||
* like a function from flash (reset vector), enter DFU mode */
|
* like a function from flash (reset vector), enter DFU mode */
|
||||||
if (((uint32_t *)app_part[1] < app_part) ||
|
if (((uint32_t *)app_part[1] < app_part) ||
|
||||||
((uint8_t *)app_part[1] > IFLASH_END))
|
((uint8_t *)app_part[1] > IFLASH_END)) {
|
||||||
return 1;
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,32 +253,76 @@ extern int main(void)
|
|||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
uint32_t reset_cause = (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos;
|
uint32_t reset_cause = (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos;
|
||||||
|
|
||||||
#if 0
|
|
||||||
led_init();
|
|
||||||
led_blink(LED_GREEN, BLINK_3O_30F);
|
|
||||||
led_blink(LED_RED, BLINK_3O_30F);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Enable watchdog for 2000ms, with no window */
|
/* Enable watchdog for 2000ms, with no window */
|
||||||
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
|
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
|
||||||
(WDT_GetPeriod(2000) << 16) | WDT_GetPeriod(2000));
|
(WDT_GetPeriod(2000) << 16) | WDT_GetPeriod(2000));
|
||||||
watchdog_configured = true;
|
watchdog_configured = true;
|
||||||
|
|
||||||
|
#ifdef PINS_LEDS
|
||||||
|
/* Configure LED */
|
||||||
|
PIO_Configure(pinsLeds, sizeof(pinsLeds));
|
||||||
|
PIO_Set(&pinsLeds[LED_NUM_RED]);
|
||||||
|
PIO_Clear(&pinsLeds[LED_NUM_GREEN]);
|
||||||
|
#endif
|
||||||
|
|
||||||
PIO_InitializeInterrupts(0);
|
PIO_InitializeInterrupts(0);
|
||||||
|
|
||||||
EEFC_ReadUniqueID(g_unique_id);
|
EEFC_ReadUniqueID(g_unique_id);
|
||||||
|
|
||||||
printf("\n\r\n\r"
|
printf("\n\r\n\r"
|
||||||
"=============================================================================\n\r"
|
"=============================================================================\n\r"
|
||||||
"DFU bootloader %s for board %s (C) 2010-2017 by Harald Welte\n\r"
|
"DFU bootloader %s for board %s\n\r"
|
||||||
|
"(C) 2010-2017 by Harald Welte, 2018-2019 by Kevin Redon\n\r"
|
||||||
"=============================================================================\n\r",
|
"=============================================================================\n\r",
|
||||||
manifest_revision, manifest_board);
|
manifest_revision, manifest_board);
|
||||||
|
|
||||||
TRACE_INFO("Chip ID: 0x%08x (Ext 0x%08x)\n\r", CHIPID->CHIPID_CIDR, CHIPID->CHIPID_EXID);
|
#if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
|
||||||
|
TRACE_INFO("Chip ID: 0x%08lx (Ext 0x%08lx)\n\r", CHIPID->CHIPID_CIDR, CHIPID->CHIPID_EXID);
|
||||||
TRACE_INFO("Serial Nr. %08x-%08x-%08x-%08x\n\r",
|
TRACE_INFO("Serial Nr. %08x-%08x-%08x-%08x\n\r",
|
||||||
g_unique_id[0], g_unique_id[1],
|
g_unique_id[0], g_unique_id[1],
|
||||||
g_unique_id[2], g_unique_id[3]);
|
g_unique_id[2], g_unique_id[3]);
|
||||||
TRACE_INFO("Reset Cause: 0x%x\n\r", reset_cause);
|
static const char* reset_causes[] = {
|
||||||
|
"general reset (first power-up reset)",
|
||||||
|
"backup reset (return from backup mode)",
|
||||||
|
"watchdog reset (watchdog fault occurred)",
|
||||||
|
"software reset (processor reset required by the software)",
|
||||||
|
"user reset (NRST pin detected low)",
|
||||||
|
};
|
||||||
|
if (reset_cause < ARRAY_SIZE(reset_causes)) {
|
||||||
|
TRACE_INFO("Reset Cause: %s\n\r", reset_causes[reset_cause]);
|
||||||
|
} else {
|
||||||
|
TRACE_INFO("Reset Cause: 0x%lx\n\r", (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
|
||||||
|
/* Find out why we are in the DFU bootloader, and not the main application */
|
||||||
|
TRACE_INFO("DFU bootloader start reason: ");
|
||||||
|
switch (USBDFU_OverrideEnterDFU()) {
|
||||||
|
case 0:
|
||||||
|
if (SCB->VTOR < IFLASH_ADDR + BOARD_DFU_BOOT_SIZE) {
|
||||||
|
TRACE_INFO_WP("unknown\n\r");
|
||||||
|
} else {
|
||||||
|
TRACE_INFO_WP("DFU is the main application\n\r");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
TRACE_INFO_WP("DFU switch requested by main application\n\r");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
TRACE_INFO_WP("bootloader forced (button pressed or jumper set)\n\r");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
TRACE_INFO_WP("stack pointer (first application word) does no point in RAM\n\r");
|
||||||
|
break;
|
||||||
|
case 4: // the is no reason
|
||||||
|
TRACE_INFO_WP("reset vector (second application word) does no point in flash\n\r");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TRACE_INFO_WP("unknown\n\r");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* clear g_dfu on power-up reset */
|
/* clear g_dfu on power-up reset */
|
||||||
if (reset_cause == 0)
|
if (reset_cause == 0)
|
||||||
@@ -222,11 +332,17 @@ extern int main(void)
|
|||||||
|
|
||||||
TRACE_INFO("USB init...\n\r");
|
TRACE_INFO("USB init...\n\r");
|
||||||
/* Signal USB reset by disabling the pull-up on USB D+ for at least 10 ms */
|
/* Signal USB reset by disabling the pull-up on USB D+ for at least 10 ms */
|
||||||
|
USBD_Disconnect();
|
||||||
|
#ifdef PIN_USB_PULLUP
|
||||||
const Pin usb_dp_pullup = PIN_USB_PULLUP;
|
const Pin usb_dp_pullup = PIN_USB_PULLUP;
|
||||||
PIO_Configure(&usb_dp_pullup, 1);
|
PIO_Configure(&usb_dp_pullup, 1);
|
||||||
PIO_Set(&usb_dp_pullup);
|
PIO_Set(&usb_dp_pullup);
|
||||||
mdelay(15);
|
#endif
|
||||||
|
mdelay(50);
|
||||||
|
#ifdef PIN_USB_PULLUP
|
||||||
PIO_Clear(&usb_dp_pullup);
|
PIO_Clear(&usb_dp_pullup);
|
||||||
|
#endif
|
||||||
|
|
||||||
USBDFU_Initialize(&dfu_descriptors);
|
USBDFU_Initialize(&dfu_descriptors);
|
||||||
|
|
||||||
while (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
while (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
||||||
@@ -234,8 +350,8 @@ extern int main(void)
|
|||||||
check_exec_dbg_cmd();
|
check_exec_dbg_cmd();
|
||||||
#if 1
|
#if 1
|
||||||
if (i >= MAX_USB_ITER * 3) {
|
if (i >= MAX_USB_ITER * 3) {
|
||||||
TRACE_ERROR("Resetting board (USB could "
|
TRACE_ERROR("Resetting board (USB could not be configured)\n\r");
|
||||||
"not be configured)\n\r");
|
g_dfu->magic = USB_DFU_MAGIC; // start the bootloader after reboot
|
||||||
USBD_Disconnect();
|
USBD_Disconnect();
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
sysmocom - s.f.m.c. GmbH
|
sysmocom - s.f.m.c. GmbH
|
||||||
SIMtrace 2 compatible device
|
PRODUCT_STRING
|
||||||
DFU (Device Firmware Upgrade)
|
DFU (Device Firmware Upgrade)
|
||||||
RAM
|
RAM
|
||||||
Flash (Application Partition)
|
Flash (Application Partition)
|
||||||
|
Flash (Bootloader Partition)
|
||||||
|
|||||||
3
firmware/apps/freq_ctr/Makefile
Normal file
3
firmware/apps/freq_ctr/Makefile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
C_FILES += $(C_LIBUSB_RT)
|
||||||
|
|
||||||
|
C_FILES += freq_ctr.c
|
||||||
55
firmware/apps/freq_ctr/freq_ctr.c
Normal file
55
firmware/apps/freq_ctr/freq_ctr.c
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "utils.h"
|
||||||
|
#include "tc_etu.h"
|
||||||
|
#include "chip.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* pins for Channel 0 of TC-block 0 */
|
||||||
|
#define PIN_TIOA0 {PIO_PA0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
|
||||||
|
/* pins for Channel 1 of TC-block 0 */
|
||||||
|
#define PIN_TIOA1 {PIO_PA15, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PIN_TCLK1 {PIO_PA28, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
|
||||||
|
static const Pin pins_tc[] = { PIN_TIOA0, PIN_TIOA1, PIN_TCLK1 };
|
||||||
|
|
||||||
|
static TcChannel *tc1 = &TC0->TC_CHANNEL[1];
|
||||||
|
|
||||||
|
void TC1_IrqHandler(void)
|
||||||
|
{
|
||||||
|
uint32_t sr = tc1->TC_SR;
|
||||||
|
printf("TC1=%lu; SR=0x%08lx\r\n", tc1->TC_RA, sr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freq_ctr_init(void)
|
||||||
|
{
|
||||||
|
TcChannel *tc0 = &TC0->TC_CHANNEL[0];
|
||||||
|
|
||||||
|
PIO_Configure(pins_tc, ARRAY_SIZE(pins_tc));
|
||||||
|
|
||||||
|
PMC_EnablePeripheral(ID_TC0);
|
||||||
|
PMC_EnablePeripheral(ID_TC1);
|
||||||
|
|
||||||
|
/* route TCLK1 to XC1 */
|
||||||
|
TC0->TC_BMR &= ~TC_BMR_TC1XC1S_Msk;
|
||||||
|
TC0->TC_BMR |= TC_BMR_TC1XC1S_TCLK1;
|
||||||
|
|
||||||
|
/* TC0 in wveform mode: Run from SCLK. Raise TIOA on RA; lower TIOA on RC + trigger */
|
||||||
|
tc0->TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK5 | TC_CMR_BURST_NONE |
|
||||||
|
TC_CMR_EEVTEDG_NONE | TC_CMR_WAVSEL_UP_RC | TC_CMR_WAVE |
|
||||||
|
TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR;
|
||||||
|
tc0->TC_RA = 16384; /* set high at 16384 */
|
||||||
|
tc0->TC_RC = 32786; /* set low at 32786 */
|
||||||
|
|
||||||
|
/* TC1 in capture mode: Run from XC1. Trigger on TIOA rising. Load RA on rising */
|
||||||
|
tc1->TC_CMR = TC_CMR_TCCLKS_XC1 | TC_CMR_BURST_NONE |
|
||||||
|
TC_CMR_ETRGEDG_RISING | TC_CMR_ABETRG | TC_CMR_LDRA_RISING;
|
||||||
|
/* Interrupt us if the external trigger happens */
|
||||||
|
tc1->TC_IER = TC_IER_ETRGS;
|
||||||
|
NVIC_EnableIRQ(TC1_IRQn);
|
||||||
|
|
||||||
|
TC0->TC_BCR = TC_BCR_SYNC;
|
||||||
|
|
||||||
|
tc0->TC_CCR = TC_CCR_CLKEN|TC_CCR_SWTRG;
|
||||||
|
tc1->TC_CCR = TC_CCR_CLKEN|TC_CCR_SWTRG;
|
||||||
|
}
|
||||||
54
firmware/apps/freq_ctr/main.c
Normal file
54
firmware/apps/freq_ctr/main.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "osmocom/core/timer.h"
|
||||||
|
|
||||||
|
extern void freq_ctr_init(void);
|
||||||
|
|
||||||
|
/* returns '1' in case we should break any endless loop */
|
||||||
|
static void check_exec_dbg_cmd(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (!UART_IsRxReady())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ch = UART_GetChar();
|
||||||
|
|
||||||
|
board_exec_dbg_cmd(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int main(void)
|
||||||
|
{
|
||||||
|
led_init();
|
||||||
|
led_blink(LED_RED, BLINK_ALWAYS_ON);
|
||||||
|
led_blink(LED_GREEN, BLINK_ALWAYS_ON);
|
||||||
|
|
||||||
|
/* Enable watchdog for 2000 ms, with no window */
|
||||||
|
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
|
||||||
|
(WDT_GetPeriod(2000) << 16) | WDT_GetPeriod(2000));
|
||||||
|
|
||||||
|
PIO_InitializeInterrupts(0);
|
||||||
|
|
||||||
|
|
||||||
|
printf("\n\r\n\r"
|
||||||
|
"=============================================================================\n\r"
|
||||||
|
"Freq Ctr firmware " GIT_VERSION " (C) 2019 by Harald Welte\n\r"
|
||||||
|
"=============================================================================\n\r");
|
||||||
|
|
||||||
|
board_main_top();
|
||||||
|
|
||||||
|
TRACE_INFO("starting frequency counter...\n\r");
|
||||||
|
freq_ctr_init();
|
||||||
|
|
||||||
|
TRACE_INFO("entering main loop...\n\r");
|
||||||
|
while (1) {
|
||||||
|
WDT_Restart(WDT);
|
||||||
|
|
||||||
|
check_exec_dbg_cmd();
|
||||||
|
osmo_timers_prepare();
|
||||||
|
osmo_timers_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
10
firmware/apps/freq_ctr/usb_strings.txt
Normal file
10
firmware/apps/freq_ctr/usb_strings.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
sysmocom - s.f.m.c. GmbH
|
||||||
|
PRODUCT_STRING
|
||||||
|
SIMtrace Sniffer
|
||||||
|
SIMtrace CCID
|
||||||
|
SIMtrace Card Emulation
|
||||||
|
SIMtrace MITM
|
||||||
|
CardEmulator Modem 1
|
||||||
|
CardEmulator Modem 2
|
||||||
|
CardEmulator Modem 3
|
||||||
|
CardEmulator Modem 4
|
||||||
3
firmware/apps/gpio_test/Makefile
Normal file
3
firmware/apps/gpio_test/Makefile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
C_FILES += $(C_LIBUSB_RT)
|
||||||
|
|
||||||
|
C_FILES += gpio_test.c
|
||||||
8
firmware/apps/gpio_test/gpio_test.c
Normal file
8
firmware/apps/gpio_test/gpio_test.c
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "utils.h"
|
||||||
|
#include "chip.h"
|
||||||
|
|
||||||
|
void gpio_test_init(void)
|
||||||
|
{
|
||||||
|
printf("FIXME run tests here\n\r");
|
||||||
|
}
|
||||||
54
firmware/apps/gpio_test/main.c
Normal file
54
firmware/apps/gpio_test/main.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "osmocom/core/timer.h"
|
||||||
|
|
||||||
|
extern void gpio_test_init(void);
|
||||||
|
|
||||||
|
/* returns '1' in case we should break any endless loop */
|
||||||
|
static void check_exec_dbg_cmd(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (!UART_IsRxReady())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ch = UART_GetChar();
|
||||||
|
|
||||||
|
board_exec_dbg_cmd(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int main(void)
|
||||||
|
{
|
||||||
|
led_init();
|
||||||
|
led_blink(LED_RED, BLINK_ALWAYS_ON);
|
||||||
|
led_blink(LED_GREEN, BLINK_ALWAYS_ON);
|
||||||
|
|
||||||
|
/* Enable watchdog for 2000 ms, with no window */
|
||||||
|
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
|
||||||
|
(WDT_GetPeriod(2000) << 16) | WDT_GetPeriod(2000));
|
||||||
|
|
||||||
|
PIO_InitializeInterrupts(0);
|
||||||
|
|
||||||
|
|
||||||
|
printf("\n\r\n\r"
|
||||||
|
"=============================================================================\n\r"
|
||||||
|
"GPIO Test firmware " GIT_VERSION " (C) 2019 Sysmocom GmbH\n\r"
|
||||||
|
"=============================================================================\n\r");
|
||||||
|
|
||||||
|
board_main_top();
|
||||||
|
|
||||||
|
TRACE_INFO("starting gpio test...\n\r");
|
||||||
|
gpio_test_init();
|
||||||
|
|
||||||
|
TRACE_INFO("entering main loop...\n\r");
|
||||||
|
while (1) {
|
||||||
|
WDT_Restart(WDT);
|
||||||
|
|
||||||
|
check_exec_dbg_cmd();
|
||||||
|
osmo_timers_prepare();
|
||||||
|
osmo_timers_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
10
firmware/apps/gpio_test/usb_strings.txt
Normal file
10
firmware/apps/gpio_test/usb_strings.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
sysmocom - s.f.m.c. GmbH
|
||||||
|
PRODUCT_STRING
|
||||||
|
SIMtrace Sniffer
|
||||||
|
SIMtrace CCID
|
||||||
|
SIMtrace Card Emulation
|
||||||
|
SIMtrace MITM
|
||||||
|
CardEmulator Modem 1
|
||||||
|
CardEmulator Modem 2
|
||||||
|
CardEmulator Modem 3
|
||||||
|
CardEmulator Modem 4
|
||||||
3
firmware/apps/trace/Makefile
Normal file
3
firmware/apps/trace/Makefile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
C_FILES += $(C_LIBUSB_RT)
|
||||||
|
|
||||||
|
C_FILES += card_emu.c cciddriver.c iso7816_4.c iso7816_fidi.c mitm.c mode_cardemu.c mode_ccid.c simtrace_iso7816.c sniffer.c tc_etu.c usb.c
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
/* SIMtrace 2 firmware sniffer application
|
||||||
|
*
|
||||||
|
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 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.
|
||||||
|
*/
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Headers
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "simtrace.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "main_common.h"
|
||||||
|
#include "osmocom/core/timer.h"
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Internal variables
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
/* static initialization, called whether or not the usb config is active */
|
||||||
|
void (*configure) (void);
|
||||||
|
/* initialization function after the config was selected */
|
||||||
|
void (*init) (void);
|
||||||
|
/* de-initialization before selecting new config */
|
||||||
|
void (*exit) (void);
|
||||||
|
/* main loop content for given configuration */
|
||||||
|
void (*run) (void);
|
||||||
|
/* Interrupt handler for USART0 */
|
||||||
|
void (*usart0_irq) (void);
|
||||||
|
/* Interrupt handler for USART1 */
|
||||||
|
void (*usart1_irq) (void);
|
||||||
|
} conf_func;
|
||||||
|
|
||||||
|
static const conf_func config_func_ptrs[] = {
|
||||||
|
/* array slot 0 is empty, usb configs start at 1 */
|
||||||
|
#ifdef HAVE_SNIFFER
|
||||||
|
[CFG_NUM_SNIFF] = {
|
||||||
|
.configure = Sniffer_configure,
|
||||||
|
.init = Sniffer_init,
|
||||||
|
.exit = Sniffer_exit,
|
||||||
|
.run = Sniffer_run,
|
||||||
|
.usart0_irq = Sniffer_usart0_irq,
|
||||||
|
.usart1_irq = Sniffer_usart1_irq,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CCID
|
||||||
|
[CFG_NUM_CCID] = {
|
||||||
|
.configure = CCID_configure,
|
||||||
|
.init = CCID_init,
|
||||||
|
.exit = CCID_exit,
|
||||||
|
.run = CCID_run,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CARDEM
|
||||||
|
[CFG_NUM_PHONE] = {
|
||||||
|
.configure = mode_cardemu_configure,
|
||||||
|
.init = mode_cardemu_init,
|
||||||
|
.exit = mode_cardemu_exit,
|
||||||
|
.run = mode_cardemu_run,
|
||||||
|
.usart0_irq = mode_cardemu_usart0_irq,
|
||||||
|
.usart1_irq = mode_cardemu_usart1_irq,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_MITM
|
||||||
|
[CFG_NUM_MITM] = {
|
||||||
|
.configure = MITM_configure,
|
||||||
|
.init = MITM_init,
|
||||||
|
.exit = MITM_exit,
|
||||||
|
.run = MITM_run,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Internal variables
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
#if defined(HAVE_SNIFFER)
|
||||||
|
static volatile enum confNum simtrace_config = CFG_NUM_SNIFF;
|
||||||
|
#elif defined(HAVE_CARDEM)
|
||||||
|
static volatile enum confNum simtrace_config = CFG_NUM_PHONE;
|
||||||
|
#elif defined(HAVE_CCID)
|
||||||
|
static volatile enum confNum simtrace_config = CFG_NUM_CCID;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Callbacks
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
|
||||||
|
{
|
||||||
|
TRACE_INFO_WP("cfgChanged%d ", cfgnum);
|
||||||
|
simtrace_config = cfgnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USART1_IrqHandler(void)
|
||||||
|
{
|
||||||
|
if (config_func_ptrs[simtrace_config].usart1_irq)
|
||||||
|
config_func_ptrs[simtrace_config].usart1_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USART0_IrqHandler(void)
|
||||||
|
{
|
||||||
|
if (config_func_ptrs[simtrace_config].usart0_irq)
|
||||||
|
config_func_ptrs[simtrace_config].usart0_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns '1' in case we should break any endless loop */
|
||||||
|
static void check_exec_dbg_cmd(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (!UART_IsRxReady())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ch = UART_GetChar();
|
||||||
|
|
||||||
|
board_exec_dbg_cmd(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Main
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
#define MAX_USB_ITER BOARD_MCK/72 // This should be around a second
|
||||||
|
extern int main(void)
|
||||||
|
{
|
||||||
|
uint8_t isUsbConnected = 0;
|
||||||
|
enum confNum last_simtrace_config = simtrace_config;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
/* Configure LED output
|
||||||
|
* red on = power
|
||||||
|
* red blink = error
|
||||||
|
* green on = running
|
||||||
|
* green blink = activity
|
||||||
|
*/
|
||||||
|
led_init();
|
||||||
|
led_blink(LED_RED, BLINK_ALWAYS_ON);
|
||||||
|
led_blink(LED_GREEN, BLINK_ALWAYS_ON);
|
||||||
|
|
||||||
|
/* Enable watchdog for 2000 ms, with no window */
|
||||||
|
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
|
||||||
|
(WDT_GetPeriod(2000) << 16) | WDT_GetPeriod(2000));
|
||||||
|
|
||||||
|
PIO_InitializeInterrupts(0);
|
||||||
|
|
||||||
|
print_banner();
|
||||||
|
board_main_top();
|
||||||
|
|
||||||
|
TRACE_INFO("USB init...\n\r");
|
||||||
|
SIMtrace_USB_Initialize();
|
||||||
|
|
||||||
|
while (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
||||||
|
WDT_Restart(WDT);
|
||||||
|
check_exec_dbg_cmd();
|
||||||
|
#if 0
|
||||||
|
if (i >= MAX_USB_ITER * 3) {
|
||||||
|
TRACE_ERROR("Resetting board (USB could "
|
||||||
|
"not be configured)\n\r");
|
||||||
|
USBD_Disconnect();
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_INFO("calling configure of all configurations...\n\r");
|
||||||
|
for (i = 1; i < ARRAY_SIZE(config_func_ptrs); i++) {
|
||||||
|
if (config_func_ptrs[i].configure)
|
||||||
|
config_func_ptrs[i].configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_INFO("calling init of config %u...\n\r", simtrace_config);
|
||||||
|
config_func_ptrs[simtrace_config].init();
|
||||||
|
last_simtrace_config = simtrace_config;
|
||||||
|
|
||||||
|
TRACE_INFO("entering main loop...\n\r");
|
||||||
|
while (1) {
|
||||||
|
WDT_Restart(WDT);
|
||||||
|
#if TRACE_LEVEL >= TRACE_LEVEL_DEBUG
|
||||||
|
const char rotor[] = { '-', '\\', '|', '/' };
|
||||||
|
putchar('\b');
|
||||||
|
putchar(rotor[i++ % ARRAY_SIZE(rotor)]);
|
||||||
|
#endif
|
||||||
|
check_exec_dbg_cmd();
|
||||||
|
osmo_timers_prepare();
|
||||||
|
osmo_timers_update();
|
||||||
|
|
||||||
|
if (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
||||||
|
|
||||||
|
if (isUsbConnected) {
|
||||||
|
isUsbConnected = 0;
|
||||||
|
}
|
||||||
|
} else if (isUsbConnected == 0) {
|
||||||
|
TRACE_INFO("USB is now configured\n\r");
|
||||||
|
|
||||||
|
isUsbConnected = 1;
|
||||||
|
}
|
||||||
|
if (last_simtrace_config != simtrace_config) {
|
||||||
|
TRACE_INFO("USB config chg %u -> %u\n\r",
|
||||||
|
last_simtrace_config, simtrace_config);
|
||||||
|
config_func_ptrs[last_simtrace_config].exit();
|
||||||
|
config_func_ptrs[simtrace_config].init();
|
||||||
|
last_simtrace_config = simtrace_config;
|
||||||
|
} else {
|
||||||
|
config_func_ptrs[simtrace_config].run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
10
firmware/apps/trace/usb_strings.txt
Normal file
10
firmware/apps/trace/usb_strings.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
sysmocom - s.f.m.c. GmbH
|
||||||
|
PRODUCT_STRING
|
||||||
|
SIMtrace Sniffer
|
||||||
|
SIMtrace CCID
|
||||||
|
SIMtrace Card Emulation
|
||||||
|
SIMtrace MITM
|
||||||
|
CardEmulator Modem 1
|
||||||
|
CardEmulator Modem 2
|
||||||
|
CardEmulator Modem 3
|
||||||
|
CardEmulator Modem 4
|
||||||
@@ -1,4 +1,21 @@
|
|||||||
// FIXME: Copyright license here
|
/* SIMtrace 2 firmware card emulation, CCID, and sniffer application
|
||||||
|
*
|
||||||
|
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Headers
|
* Headers
|
||||||
*------------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------------*/
|
||||||
@@ -9,8 +26,6 @@
|
|||||||
#include "req_ctx.h"
|
#include "req_ctx.h"
|
||||||
#include <osmocom/core/timer.h>
|
#include <osmocom/core/timer.h>
|
||||||
|
|
||||||
unsigned int g_unique_id[4];
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Internal variables
|
* Internal variables
|
||||||
*------------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------------*/
|
||||||
@@ -132,17 +147,7 @@ extern int main(void)
|
|||||||
|
|
||||||
PIO_InitializeInterrupts(0);
|
PIO_InitializeInterrupts(0);
|
||||||
|
|
||||||
EEFC_ReadUniqueID(g_unique_id);
|
print_banner();
|
||||||
|
|
||||||
printf("\r\n\r\n"
|
|
||||||
"=============================================================================\r\n"
|
|
||||||
"SIMtrace2 firmware " GIT_REVISION " (C) 2010-2017 by Harald Welte\r\n"
|
|
||||||
"=============================================================================\r\n");
|
|
||||||
|
|
||||||
TRACE_INFO("Serial Nr. %08x-%08x-%08x-%08x\r\n",
|
|
||||||
g_unique_id[0], g_unique_id[1],
|
|
||||||
g_unique_id[2], g_unique_id[3]);
|
|
||||||
|
|
||||||
board_main_top();
|
board_main_top();
|
||||||
|
|
||||||
TRACE_INFO("USB init...\r\n");
|
TRACE_INFO("USB init...\r\n");
|
||||||
|
|||||||
@@ -45,11 +45,6 @@
|
|||||||
* Headers
|
* Headers
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef TRACE_LEVEL
|
|
||||||
#undef TRACE_LEVEL
|
|
||||||
#endif
|
|
||||||
#define TRACE_LEVEL TRACE_LEVEL_WARNING
|
|
||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
#include "USBD_HAL.h"
|
#include "USBD_HAL.h"
|
||||||
#include <usb/device/dfu/dfu.h>
|
#include <usb/device/dfu/dfu.h>
|
||||||
@@ -1082,6 +1077,14 @@ static inline uint8_t UDP_Read(uint8_t bEndpoint,
|
|||||||
* Exported functions
|
* Exported functions
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t USBD_GetEndpointSize(uint8_t bEndpoint)
|
||||||
|
{
|
||||||
|
Endpoint *pEndpoint = &(endpoints[bEndpoint]);
|
||||||
|
|
||||||
|
return pEndpoint->size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* USBD (UDP) interrupt handler
|
* USBD (UDP) interrupt handler
|
||||||
* Manages device resume, suspend, end of bus reset.
|
* Manages device resume, suspend, end of bus reset.
|
||||||
@@ -1138,7 +1141,7 @@ void USBD_IrqHandler(void)
|
|||||||
/* Resume (Wakeup) */
|
/* Resume (Wakeup) */
|
||||||
if ((status & (UDP_ISR_WAKEUP | UDP_ISR_RXRSM)) != 0) {
|
if ((status & (UDP_ISR_WAKEUP | UDP_ISR_RXRSM)) != 0) {
|
||||||
|
|
||||||
TRACE_INFO_WP("Res ");
|
TRACE_DEBUG_WP("Res ");
|
||||||
/* Clear and disable resume interrupts */
|
/* Clear and disable resume interrupts */
|
||||||
UDP->UDP_ICR = UDP_ICR_WAKEUP | UDP_ICR_RXRSM | UDP_ICR_RXSUSP;
|
UDP->UDP_ICR = UDP_ICR_WAKEUP | UDP_ICR_RXRSM | UDP_ICR_RXSUSP;
|
||||||
UDP->UDP_IDR = UDP_IDR_WAKEUP | UDP_IDR_RXRSM;
|
UDP->UDP_IDR = UDP_IDR_WAKEUP | UDP_IDR_RXRSM;
|
||||||
@@ -1150,7 +1153,7 @@ void USBD_IrqHandler(void)
|
|||||||
This interrupt is always treated last (hence the '==') */
|
This interrupt is always treated last (hence the '==') */
|
||||||
if (status == UDP_ISR_RXSUSP) {
|
if (status == UDP_ISR_RXSUSP) {
|
||||||
|
|
||||||
TRACE_INFO_WP("Susp ");
|
TRACE_DEBUG_WP("Susp ");
|
||||||
/* Enable wakeup */
|
/* Enable wakeup */
|
||||||
UDP->UDP_IER = UDP_IER_WAKEUP | UDP_IER_RXRSM;
|
UDP->UDP_IER = UDP_IER_WAKEUP | UDP_IER_RXRSM;
|
||||||
/* Acknowledge interrupt */
|
/* Acknowledge interrupt */
|
||||||
@@ -1161,19 +1164,26 @@ void USBD_IrqHandler(void)
|
|||||||
/* End of bus reset */
|
/* End of bus reset */
|
||||||
else if ((status & UDP_ISR_ENDBUSRES) != 0) {
|
else if ((status & UDP_ISR_ENDBUSRES) != 0) {
|
||||||
|
|
||||||
TRACE_INFO_WP("EoBRes ");
|
TRACE_DEBUG_WP("EoBRes ");
|
||||||
|
|
||||||
#if defined(BOARD_USB_DFU)
|
#if defined(BOARD_USB_DFU)
|
||||||
#if defined(APPLICATION_dfu)
|
#if defined(APPLICATION_dfu)
|
||||||
/* if we are currently in the DFU bootloader, and we are beyond
|
/* if we are currently in the DFU bootloader, and we are beyond
|
||||||
* the MANIFEST stage, we shall switch to the normal
|
* the MANIFEST stage, we shall switch to the normal
|
||||||
* application */
|
* application */
|
||||||
if (g_dfu->past_manifest)
|
if (g_dfu->past_manifest) {
|
||||||
|
#if defined(ENVIRONMENT_flash)
|
||||||
USBDFU_SwitchToApp();
|
USBDFU_SwitchToApp();
|
||||||
|
#elif defined(ENVIRONMENT_dfu)
|
||||||
|
USBDFU_SwitchToDFU();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* if we are currently in the main application, and we are in
|
/* if we are currently in the main application, and we are in
|
||||||
* appDETACH state, switch into the DFU bootloader */
|
* appDETACH state or past downloading, switch into the DFU bootloader.
|
||||||
if (g_dfu->state == DFU_STATE_appDETACH)
|
*/
|
||||||
|
if (g_dfu->state == DFU_STATE_appDETACH || g_dfu->state == DFU_STATE_dfuMANIFEST)
|
||||||
DFURT_SwitchToDFU();
|
DFURT_SwitchToDFU();
|
||||||
#endif /* APPLICATION_dfu */
|
#endif /* APPLICATION_dfu */
|
||||||
#endif /* BOARD_USB_DFU */
|
#endif /* BOARD_USB_DFU */
|
||||||
@@ -1202,7 +1212,7 @@ void USBD_IrqHandler(void)
|
|||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
|
|
||||||
TRACE_INFO_WP("\n\r - ");
|
TRACE_DEBUG_WP("\n\r - ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eptnum++;
|
eptnum++;
|
||||||
@@ -1211,7 +1221,7 @@ void USBD_IrqHandler(void)
|
|||||||
|
|
||||||
/* Toggle LED back to its previous state */
|
/* Toggle LED back to its previous state */
|
||||||
TRACE_DEBUG_WP("!");
|
TRACE_DEBUG_WP("!");
|
||||||
TRACE_INFO_WP("\n\r");
|
TRACE_DEBUG_WP("\n\r");
|
||||||
if (USBD_GetState() >= USBD_STATE_POWERED) {
|
if (USBD_GetState() >= USBD_STATE_POWERED) {
|
||||||
|
|
||||||
//LED_Clear(USBD_LEDUSB);
|
//LED_Clear(USBD_LEDUSB);
|
||||||
@@ -1361,7 +1371,7 @@ uint8_t USBD_HAL_ConfigureEP(const USBEndpointDescriptor *pDescriptor)
|
|||||||
UDP->UDP_IER = (1 << bEndpoint);
|
UDP->UDP_IER = (1 << bEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_INFO_WP("CfgEp%d ", bEndpoint);
|
TRACE_DEBUG_WP("CfgEp%d ", bEndpoint);
|
||||||
return bEndpoint;
|
return bEndpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1529,7 +1539,7 @@ void USBD_HAL_RemoteWakeUp(void)
|
|||||||
UDP_EnableUsbClock();
|
UDP_EnableUsbClock();
|
||||||
UDP_EnableTransceiver();
|
UDP_EnableTransceiver();
|
||||||
|
|
||||||
TRACE_INFO_WP("RWUp ");
|
TRACE_DEBUG_WP("RWUp ");
|
||||||
|
|
||||||
// Activates a remote wakeup (edge on ESR), then clear ESR
|
// Activates a remote wakeup (edge on ESR), then clear ESR
|
||||||
UDP->UDP_GLB_STAT |= UDP_GLB_STAT_ESR;
|
UDP->UDP_GLB_STAT |= UDP_GLB_STAT_ESR;
|
||||||
@@ -1662,6 +1672,10 @@ uint8_t USBD_HAL_Halt(uint8_t bEndpoint, uint8_t ctl)
|
|||||||
UDP->UDP_RST_EP |= 1 << bEndpoint;
|
UDP->UDP_RST_EP |= 1 << bEndpoint;
|
||||||
UDP->UDP_RST_EP &= ~(1 << bEndpoint);
|
UDP->UDP_RST_EP &= ~(1 << bEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This fixes a weird bug with regard to ping-pong OUT endpoints */
|
||||||
|
UDP->UDP_RST_EP |= 1 << bEndpoint;
|
||||||
|
UDP->UDP_RST_EP &= ~(1 << bEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return Halt status */
|
/* Return Halt status */
|
||||||
@@ -1692,7 +1706,10 @@ void USBD_HAL_Suspend(void)
|
|||||||
/* The device enters the Suspended state */
|
/* The device enters the Suspended state */
|
||||||
UDP_DisableTransceiver();
|
UDP_DisableTransceiver();
|
||||||
UDP_DisableUsbClock();
|
UDP_DisableUsbClock();
|
||||||
UDP_DisablePeripheralClock();
|
/* Don't disable peripheral clock; this somehow breaks completion of any IN transfers
|
||||||
|
* that have already been written to the peripheral, and which we expect to complete
|
||||||
|
* after resume */
|
||||||
|
//UDP_DisablePeripheralClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ extern void EFC_TranslateAddress( Efc** ppEfc, uint32_t dwAddress, uint16_t* pwP
|
|||||||
wPage = (dwAddress - IFLASH_ADDR) / IFLASH_PAGE_SIZE;
|
wPage = (dwAddress - IFLASH_ADDR) / IFLASH_PAGE_SIZE;
|
||||||
wOffset = (dwAddress - IFLASH_ADDR) % IFLASH_PAGE_SIZE;
|
wOffset = (dwAddress - IFLASH_ADDR) % IFLASH_PAGE_SIZE;
|
||||||
|
|
||||||
TRACE_DEBUG( "Translated 0x%08X to page=%d and offset=%d\n\r", dwAddress, wPage, wOffset ) ;
|
TRACE_DEBUG( "Translated 0x%08lX to page=%d and offset=%d\n\r", dwAddress, wPage, wOffset ) ;
|
||||||
/* Store values */
|
/* Store values */
|
||||||
if ( pEfc )
|
if ( pEfc )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* ATMEL Microcontroller Software Support
|
* ATMEL Microcontroller Software Support
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2009, Atmel Corporation
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
* Copyright (c) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -42,6 +43,7 @@
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
#define printf printf_sync
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
* Exported functions
|
* Exported functions
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ static void ComputeLockRange( uint32_t dwStart, uint32_t dwEnd, uint32_t *pdwAct
|
|||||||
// Store actual page numbers
|
// Store actual page numbers
|
||||||
EFC_ComputeAddress( pStartEfc, wActualStartPage, 0, pdwActualStart ) ;
|
EFC_ComputeAddress( pStartEfc, wActualStartPage, 0, pdwActualStart ) ;
|
||||||
EFC_ComputeAddress( pEndEfc, wActualEndPage, 0, pdwActualEnd ) ;
|
EFC_ComputeAddress( pEndEfc, wActualEndPage, 0, pdwActualEnd ) ;
|
||||||
TRACE_DEBUG( "Actual lock range is 0x%06X - 0x%06X\n\r", *pdwActualStart, *pdwActualEnd ) ;
|
TRACE_DEBUG( "Actual lock range is 0x%06lX - 0x%06lX\n\r", *pdwActualStart, *pdwActualEnd ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ void EEFC_ReadUniqueID(unsigned int *pdwUniqueID)
|
|||||||
{
|
{
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
|
||||||
|
/* disable interrupts, as interrupt vectors are stored in flash,
|
||||||
|
* and after STUI was issued, we can no longer access flassh until
|
||||||
|
* SPUI complets */
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
/* Errata / Workaround: Set bit 16 of EEFC Flash Mode Register
|
/* Errata / Workaround: Set bit 16 of EEFC Flash Mode Register
|
||||||
* to 1 */
|
* to 1 */
|
||||||
EFC->EEFC_FMR |= (1 << 16);
|
EFC->EEFC_FMR |= (1 << 16);
|
||||||
@@ -40,4 +45,6 @@ void EEFC_ReadUniqueID(unsigned int *pdwUniqueID)
|
|||||||
do {
|
do {
|
||||||
status = EFC->EEFC_FSR;
|
status = EFC->EEFC_FSR;
|
||||||
} while ((status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
|
} while ((status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
|
||||||
|
|
||||||
|
__enable_irq();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ static void GetDescriptor(
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
case USBGenericDescriptor_DEVICE:
|
case USBGenericDescriptor_DEVICE:
|
||||||
TRACE_INFO_WP("Dev ");
|
TRACE_DEBUG_WP("Dev ");
|
||||||
|
|
||||||
/* Adjust length and send descriptor */
|
/* Adjust length and send descriptor */
|
||||||
|
|
||||||
@@ -263,7 +263,7 @@ static void GetDescriptor(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericDescriptor_CONFIGURATION:
|
case USBGenericDescriptor_CONFIGURATION:
|
||||||
TRACE_INFO_WP("Cfg ");
|
TRACE_DEBUG_WP("Cfg ");
|
||||||
|
|
||||||
/* Adjust length and send descriptor */
|
/* Adjust length and send descriptor */
|
||||||
|
|
||||||
@@ -280,7 +280,7 @@ static void GetDescriptor(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericDescriptor_DEVICEQUALIFIER:
|
case USBGenericDescriptor_DEVICEQUALIFIER:
|
||||||
TRACE_INFO_WP("Qua ");
|
TRACE_DEBUG_WP("Qua ");
|
||||||
|
|
||||||
/* Check if descriptor exists */
|
/* Check if descriptor exists */
|
||||||
|
|
||||||
@@ -301,7 +301,7 @@ static void GetDescriptor(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericDescriptor_OTHERSPEEDCONFIGURATION:
|
case USBGenericDescriptor_OTHERSPEEDCONFIGURATION:
|
||||||
TRACE_INFO_WP("OSC ");
|
TRACE_DEBUG_WP("OSC ");
|
||||||
|
|
||||||
/* Check if descriptor exists */
|
/* Check if descriptor exists */
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@ static void GetDescriptor(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericDescriptor_STRING:
|
case USBGenericDescriptor_STRING:
|
||||||
TRACE_INFO_WP("Str%d ", indexRDesc);
|
TRACE_DEBUG_WP("Str%d ", indexRDesc);
|
||||||
|
|
||||||
/* Check if descriptor exists */
|
/* Check if descriptor exists */
|
||||||
|
|
||||||
@@ -504,13 +504,13 @@ void USBDDriver_RequestHandler(
|
|||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
|
|
||||||
TRACE_INFO_WP("Std ");
|
TRACE_DEBUG_WP("Std ");
|
||||||
|
|
||||||
/* Check request code */
|
/* Check request code */
|
||||||
switch (USBGenericRequest_GetRequest(pRequest)) {
|
switch (USBGenericRequest_GetRequest(pRequest)) {
|
||||||
|
|
||||||
case USBGenericRequest_GETDESCRIPTOR:
|
case USBGenericRequest_GETDESCRIPTOR:
|
||||||
TRACE_INFO_WP("gDesc ");
|
TRACE_DEBUG_WP("gDesc ");
|
||||||
|
|
||||||
/* Send the requested descriptor */
|
/* Send the requested descriptor */
|
||||||
type = USBGetDescriptorRequest_GetDescriptorType(pRequest);
|
type = USBGetDescriptorRequest_GetDescriptorType(pRequest);
|
||||||
@@ -520,7 +520,7 @@ void USBDDriver_RequestHandler(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericRequest_SETADDRESS:
|
case USBGenericRequest_SETADDRESS:
|
||||||
TRACE_INFO_WP("sAddr ");
|
TRACE_DEBUG_WP("sAddr ");
|
||||||
|
|
||||||
/* Sends a zero-length packet and then set the device address */
|
/* Sends a zero-length packet and then set the device address */
|
||||||
address = USBSetAddressRequest_GetAddress(pRequest);
|
address = USBSetAddressRequest_GetAddress(pRequest);
|
||||||
@@ -528,7 +528,7 @@ void USBDDriver_RequestHandler(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericRequest_SETCONFIGURATION:
|
case USBGenericRequest_SETCONFIGURATION:
|
||||||
TRACE_INFO_WP("sCfg ");
|
TRACE_DEBUG_WP("sCfg ");
|
||||||
|
|
||||||
/* Set the requested configuration */
|
/* Set the requested configuration */
|
||||||
cfgnum = USBSetConfigurationRequest_GetConfiguration(pRequest);
|
cfgnum = USBSetConfigurationRequest_GetConfiguration(pRequest);
|
||||||
@@ -536,27 +536,27 @@ void USBDDriver_RequestHandler(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericRequest_GETCONFIGURATION:
|
case USBGenericRequest_GETCONFIGURATION:
|
||||||
TRACE_INFO_WP("gCfg ");
|
TRACE_DEBUG_WP("gCfg ");
|
||||||
|
|
||||||
/* Send the current configuration number */
|
/* Send the current configuration number */
|
||||||
GetConfiguration(pDriver);
|
GetConfiguration(pDriver);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericRequest_GETSTATUS:
|
case USBGenericRequest_GETSTATUS:
|
||||||
TRACE_INFO_WP("gSta ");
|
TRACE_DEBUG_WP("gSta ");
|
||||||
|
|
||||||
/* Check who is the recipient */
|
/* Check who is the recipient */
|
||||||
switch (USBGenericRequest_GetRecipient(pRequest)) {
|
switch (USBGenericRequest_GetRecipient(pRequest)) {
|
||||||
|
|
||||||
case USBGenericRequest_DEVICE:
|
case USBGenericRequest_DEVICE:
|
||||||
TRACE_INFO_WP("Dev ");
|
TRACE_DEBUG_WP("Dev ");
|
||||||
|
|
||||||
/* Send the device status */
|
/* Send the device status */
|
||||||
GetDeviceStatus(pDriver);
|
GetDeviceStatus(pDriver);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericRequest_ENDPOINT:
|
case USBGenericRequest_ENDPOINT:
|
||||||
TRACE_INFO_WP("Ept ");
|
TRACE_DEBUG_WP("Ept ");
|
||||||
|
|
||||||
/* Send the endpoint status */
|
/* Send the endpoint status */
|
||||||
eptnum = USBGenericRequest_GetEndpointNumber(pRequest);
|
eptnum = USBGenericRequest_GetEndpointNumber(pRequest);
|
||||||
@@ -572,13 +572,13 @@ void USBDDriver_RequestHandler(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericRequest_CLEARFEATURE:
|
case USBGenericRequest_CLEARFEATURE:
|
||||||
TRACE_INFO_WP("cFeat ");
|
TRACE_DEBUG_WP("cFeat ");
|
||||||
|
|
||||||
/* Check which is the requested feature */
|
/* Check which is the requested feature */
|
||||||
switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {
|
switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {
|
||||||
|
|
||||||
case USBFeatureRequest_ENDPOINTHALT:
|
case USBFeatureRequest_ENDPOINTHALT:
|
||||||
TRACE_INFO_WP("Hlt ");
|
TRACE_DEBUG_WP("Hlt ");
|
||||||
|
|
||||||
/* Unhalt endpoint and send a zero-length packet */
|
/* Unhalt endpoint and send a zero-length packet */
|
||||||
USBD_Unhalt(USBGenericRequest_GetEndpointNumber(pRequest));
|
USBD_Unhalt(USBGenericRequest_GetEndpointNumber(pRequest));
|
||||||
@@ -586,7 +586,7 @@ void USBDDriver_RequestHandler(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBFeatureRequest_DEVICEREMOTEWAKEUP:
|
case USBFeatureRequest_DEVICEREMOTEWAKEUP:
|
||||||
TRACE_INFO_WP("RmWU ");
|
TRACE_DEBUG_WP("RmWU ");
|
||||||
|
|
||||||
/* Disable remote wake-up and send a zero-length packet */
|
/* Disable remote wake-up and send a zero-length packet */
|
||||||
pDriver->isRemoteWakeUpEnabled = 0;
|
pDriver->isRemoteWakeUpEnabled = 0;
|
||||||
@@ -602,13 +602,13 @@ void USBDDriver_RequestHandler(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericRequest_SETFEATURE:
|
case USBGenericRequest_SETFEATURE:
|
||||||
TRACE_INFO_WP("sFeat ");
|
TRACE_DEBUG_WP("sFeat ");
|
||||||
|
|
||||||
/* Check which is the selected feature */
|
/* Check which is the selected feature */
|
||||||
switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {
|
switch (USBFeatureRequest_GetFeatureSelector(pRequest)) {
|
||||||
|
|
||||||
case USBFeatureRequest_DEVICEREMOTEWAKEUP:
|
case USBFeatureRequest_DEVICEREMOTEWAKEUP:
|
||||||
TRACE_INFO_WP("RmWU ");
|
TRACE_DEBUG_WP("RmWU ");
|
||||||
|
|
||||||
/* Enable remote wake-up and send a ZLP */
|
/* Enable remote wake-up and send a ZLP */
|
||||||
pDriver->isRemoteWakeUpEnabled = 1;
|
pDriver->isRemoteWakeUpEnabled = 1;
|
||||||
@@ -616,25 +616,25 @@ void USBDDriver_RequestHandler(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBFeatureRequest_ENDPOINTHALT:
|
case USBFeatureRequest_ENDPOINTHALT:
|
||||||
TRACE_INFO_WP("Halt ");
|
TRACE_DEBUG_WP("Halt ");
|
||||||
/* Halt endpoint */
|
/* Halt endpoint */
|
||||||
USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
|
USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
|
||||||
USBD_Write(0, 0, 0, 0, 0);
|
USBD_Write(0, 0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case USBFeatureRequest_OTG_B_HNP_ENABLE:
|
case USBFeatureRequest_OTG_B_HNP_ENABLE:
|
||||||
TRACE_INFO_WP("OTG_B_HNP_ENABLE ");
|
TRACE_DEBUG_WP("OTG_B_HNP_ENABLE ");
|
||||||
pDriver->otg_features_supported |=
|
pDriver->otg_features_supported |=
|
||||||
1<<USBFeatureRequest_OTG_B_HNP_ENABLE;
|
1<<USBFeatureRequest_OTG_B_HNP_ENABLE;
|
||||||
USBD_Write(0, 0, 0, 0, 0);
|
USBD_Write(0, 0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case USBFeatureRequest_OTG_A_HNP_SUPPORT:
|
case USBFeatureRequest_OTG_A_HNP_SUPPORT:
|
||||||
TRACE_INFO_WP("OTG_A_HNP_SUPPORT ");
|
TRACE_DEBUG_WP("OTG_A_HNP_SUPPORT ");
|
||||||
pDriver->otg_features_supported |=
|
pDriver->otg_features_supported |=
|
||||||
1<<USBFeatureRequest_OTG_A_HNP_SUPPORT;
|
1<<USBFeatureRequest_OTG_A_HNP_SUPPORT;
|
||||||
USBD_Write(0, 0, 0, 0, 0);
|
USBD_Write(0, 0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT:
|
case USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT:
|
||||||
TRACE_INFO_WP("OTG_A_ALT_HNP_SUPPORT ");
|
TRACE_DEBUG_WP("OTG_A_ALT_HNP_SUPPORT ");
|
||||||
pDriver->otg_features_supported |=
|
pDriver->otg_features_supported |=
|
||||||
1<<USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT;
|
1<<USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT;
|
||||||
USBD_Write(0, 0, 0, 0, 0);
|
USBD_Write(0, 0, 0, 0, 0);
|
||||||
@@ -649,7 +649,7 @@ void USBDDriver_RequestHandler(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericRequest_SETINTERFACE:
|
case USBGenericRequest_SETINTERFACE:
|
||||||
TRACE_INFO_WP("sInterface ");
|
TRACE_DEBUG_WP("sInterface ");
|
||||||
|
|
||||||
infnum = USBInterfaceRequest_GetInterface(pRequest);
|
infnum = USBInterfaceRequest_GetInterface(pRequest);
|
||||||
setting = USBInterfaceRequest_GetAlternateSetting(pRequest);
|
setting = USBInterfaceRequest_GetAlternateSetting(pRequest);
|
||||||
@@ -657,7 +657,7 @@ void USBDDriver_RequestHandler(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBGenericRequest_GETINTERFACE:
|
case USBGenericRequest_GETINTERFACE:
|
||||||
TRACE_INFO_WP("gInterface ");
|
TRACE_DEBUG_WP("gInterface ");
|
||||||
|
|
||||||
infnum = USBInterfaceRequest_GetInterface(pRequest);
|
infnum = USBInterfaceRequest_GetInterface(pRequest);
|
||||||
GetInterface(pDriver, infnum);
|
GetInterface(pDriver, infnum);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ struct dfudata {
|
|||||||
extern struct dfudata _g_dfu;
|
extern struct dfudata _g_dfu;
|
||||||
extern struct dfudata *g_dfu;
|
extern struct dfudata *g_dfu;
|
||||||
|
|
||||||
void set_usb_serial_str(const uint8_t *serial_usbstr);
|
void set_usb_serial_str(void);
|
||||||
|
|
||||||
void DFURT_SwitchToDFU(void);
|
void DFURT_SwitchToDFU(void);
|
||||||
|
|
||||||
@@ -124,6 +124,9 @@ void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors);
|
|||||||
/* USBD tells us to switch from DFU mode to application mode */
|
/* USBD tells us to switch from DFU mode to application mode */
|
||||||
void USBDFU_SwitchToApp(void);
|
void USBDFU_SwitchToApp(void);
|
||||||
|
|
||||||
|
/* USBD tells us to switch from to DFU mode */
|
||||||
|
void USBDFU_SwitchToDFU(void);
|
||||||
|
|
||||||
/* Return values to be used by USBDFU_handle_{dn,up}load */
|
/* Return values to be used by USBDFU_handle_{dn,up}load */
|
||||||
#define DFU_RET_NOTHING 0
|
#define DFU_RET_NOTHING 0
|
||||||
#define DFU_RET_ZLP 1
|
#define DFU_RET_ZLP 1
|
||||||
|
|||||||
@@ -13,14 +13,107 @@
|
|||||||
#include <usb/common/dfu/usb_dfu.h>
|
#include <usb/common/dfu/usb_dfu.h>
|
||||||
#include <usb/device/dfu/dfu.h>
|
#include <usb/device/dfu/dfu.h>
|
||||||
|
|
||||||
|
#include "usb_strings_generated.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
STR_MANUF = 1,
|
STR_MANUF = 1,
|
||||||
STR_PROD,
|
STR_PROD,
|
||||||
STR_CONFIG,
|
STR_CONFIG,
|
||||||
|
// strings for the first alternate interface (e.g. DFU)
|
||||||
_STR_FIRST_ALT,
|
_STR_FIRST_ALT,
|
||||||
STR_SERIAL = (_STR_FIRST_ALT+BOARD_DFU_NUM_IF),
|
// serial string
|
||||||
|
STR_SERIAL = (_STR_FIRST_ALT + BOARD_DFU_NUM_IF),
|
||||||
|
// version string (on additional interface)
|
||||||
|
VERSION_CONF_STR,
|
||||||
|
VERSION_STR,
|
||||||
|
// count
|
||||||
|
STRING_DESC_CNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* string used to replace one of both DFU flash partition atlsettings */
|
||||||
|
static const unsigned char usb_string_notavailable[] = {
|
||||||
|
USBStringDescriptor_LENGTH(13),
|
||||||
|
USBGenericDescriptor_STRING,
|
||||||
|
USBStringDescriptor_UNICODE('n'),
|
||||||
|
USBStringDescriptor_UNICODE('o'),
|
||||||
|
USBStringDescriptor_UNICODE('t'),
|
||||||
|
USBStringDescriptor_UNICODE(' '),
|
||||||
|
USBStringDescriptor_UNICODE('a'),
|
||||||
|
USBStringDescriptor_UNICODE('v'),
|
||||||
|
USBStringDescriptor_UNICODE('a'),
|
||||||
|
USBStringDescriptor_UNICODE('i'),
|
||||||
|
USBStringDescriptor_UNICODE('l'),
|
||||||
|
USBStringDescriptor_UNICODE('a'),
|
||||||
|
USBStringDescriptor_UNICODE('b'),
|
||||||
|
USBStringDescriptor_UNICODE('l'),
|
||||||
|
USBStringDescriptor_UNICODE('e'),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* USB string for the serial (using 128-bit device ID) */
|
||||||
|
static unsigned char usb_string_serial[] = {
|
||||||
|
USBStringDescriptor_LENGTH(32),
|
||||||
|
USBGenericDescriptor_STRING,
|
||||||
|
USBStringDescriptor_UNICODE('0'),
|
||||||
|
USBStringDescriptor_UNICODE('0'),
|
||||||
|
USBStringDescriptor_UNICODE('1'),
|
||||||
|
USBStringDescriptor_UNICODE('1'),
|
||||||
|
USBStringDescriptor_UNICODE('2'),
|
||||||
|
USBStringDescriptor_UNICODE('2'),
|
||||||
|
USBStringDescriptor_UNICODE('3'),
|
||||||
|
USBStringDescriptor_UNICODE('3'),
|
||||||
|
USBStringDescriptor_UNICODE('4'),
|
||||||
|
USBStringDescriptor_UNICODE('4'),
|
||||||
|
USBStringDescriptor_UNICODE('5'),
|
||||||
|
USBStringDescriptor_UNICODE('5'),
|
||||||
|
USBStringDescriptor_UNICODE('6'),
|
||||||
|
USBStringDescriptor_UNICODE('6'),
|
||||||
|
USBStringDescriptor_UNICODE('7'),
|
||||||
|
USBStringDescriptor_UNICODE('7'),
|
||||||
|
USBStringDescriptor_UNICODE('8'),
|
||||||
|
USBStringDescriptor_UNICODE('8'),
|
||||||
|
USBStringDescriptor_UNICODE('9'),
|
||||||
|
USBStringDescriptor_UNICODE('9'),
|
||||||
|
USBStringDescriptor_UNICODE('a'),
|
||||||
|
USBStringDescriptor_UNICODE('a'),
|
||||||
|
USBStringDescriptor_UNICODE('b'),
|
||||||
|
USBStringDescriptor_UNICODE('b'),
|
||||||
|
USBStringDescriptor_UNICODE('c'),
|
||||||
|
USBStringDescriptor_UNICODE('c'),
|
||||||
|
USBStringDescriptor_UNICODE('d'),
|
||||||
|
USBStringDescriptor_UNICODE('d'),
|
||||||
|
USBStringDescriptor_UNICODE('e'),
|
||||||
|
USBStringDescriptor_UNICODE('e'),
|
||||||
|
USBStringDescriptor_UNICODE('f'),
|
||||||
|
USBStringDescriptor_UNICODE('f'),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* USB string for the version */
|
||||||
|
static const unsigned char usb_string_version_conf[] = {
|
||||||
|
USBStringDescriptor_LENGTH(16),
|
||||||
|
USBGenericDescriptor_STRING,
|
||||||
|
USBStringDescriptor_UNICODE('f'),
|
||||||
|
USBStringDescriptor_UNICODE('i'),
|
||||||
|
USBStringDescriptor_UNICODE('r'),
|
||||||
|
USBStringDescriptor_UNICODE('m'),
|
||||||
|
USBStringDescriptor_UNICODE('w'),
|
||||||
|
USBStringDescriptor_UNICODE('a'),
|
||||||
|
USBStringDescriptor_UNICODE('r'),
|
||||||
|
USBStringDescriptor_UNICODE('e'),
|
||||||
|
USBStringDescriptor_UNICODE(' '),
|
||||||
|
USBStringDescriptor_UNICODE('v'),
|
||||||
|
USBStringDescriptor_UNICODE('e'),
|
||||||
|
USBStringDescriptor_UNICODE('r'),
|
||||||
|
USBStringDescriptor_UNICODE('s'),
|
||||||
|
USBStringDescriptor_UNICODE('i'),
|
||||||
|
USBStringDescriptor_UNICODE('o'),
|
||||||
|
USBStringDescriptor_UNICODE('n'),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char git_version[] = GIT_VERSION;
|
||||||
|
static unsigned char usb_string_version[2 + ARRAY_SIZE(git_version) * 2 - 2];
|
||||||
|
/** array of static (from usb_strings) and runtime (serial, version) USB strings */
|
||||||
|
static const unsigned char *usb_strings_extended[STRING_DESC_CNT];
|
||||||
|
|
||||||
static const USBDeviceDescriptor fsDevice = {
|
static const USBDeviceDescriptor fsDevice = {
|
||||||
.bLength = sizeof(USBDeviceDescriptor),
|
.bLength = sizeof(USBDeviceDescriptor),
|
||||||
.bDescriptorType = USBGenericDescriptor_DEVICE,
|
.bDescriptorType = USBGenericDescriptor_DEVICE,
|
||||||
@@ -28,18 +121,14 @@ static const USBDeviceDescriptor fsDevice = {
|
|||||||
.bDeviceClass = 0,
|
.bDeviceClass = 0,
|
||||||
.bDeviceSubClass = 0,
|
.bDeviceSubClass = 0,
|
||||||
.bDeviceProtocol = 0,
|
.bDeviceProtocol = 0,
|
||||||
.bMaxPacketSize0 = BOARD_USB_ENDPOINTS_MAXPACKETSIZE(0),
|
.bMaxPacketSize0 = USBEndpointDescriptor_MAXCTRLSIZE_FS,
|
||||||
.idVendor = BOARD_USB_VENDOR_ID,
|
.idVendor = BOARD_USB_VENDOR_ID,
|
||||||
.idProduct = BOARD_DFU_USB_PRODUCT_ID,
|
.idProduct = BOARD_DFU_USB_PRODUCT_ID,
|
||||||
.bcdDevice = BOARD_USB_RELEASE,
|
.bcdDevice = BOARD_USB_RELEASE,
|
||||||
.iManufacturer = STR_MANUF,
|
.iManufacturer = STR_MANUF,
|
||||||
.iProduct = STR_PROD,
|
.iProduct = STR_PROD,
|
||||||
#ifdef BOARD_USB_SERIAL
|
|
||||||
.iSerialNumber = STR_SERIAL,
|
.iSerialNumber = STR_SERIAL,
|
||||||
#else
|
.bNumConfigurations = 2, // DFU + version configurations
|
||||||
.iSerialNumber = 0,
|
|
||||||
#endif
|
|
||||||
.bNumConfigurations = 1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Alternate Interface Descriptor, we use one per partition/memory type */
|
/* Alternate Interface Descriptor, we use one per partition/memory type */
|
||||||
@@ -52,7 +141,7 @@ static const USBDeviceDescriptor fsDevice = {
|
|||||||
.bNumEndpoints = 0, \
|
.bNumEndpoints = 0, \
|
||||||
.bInterfaceClass = 0xfe, \
|
.bInterfaceClass = 0xfe, \
|
||||||
.bInterfaceSubClass = 1, \
|
.bInterfaceSubClass = 1, \
|
||||||
.iInterface = (_STR_FIRST_ALT+ALT), \
|
.iInterface = (_STR_FIRST_ALT + ALT), \
|
||||||
.bInterfaceProtocol = 2, \
|
.bInterfaceProtocol = 2, \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,17 +174,79 @@ const struct dfu_desc dfu_cfg_descriptor = {
|
|||||||
.func_dfu = DFU_FUNC_DESC
|
.func_dfu = DFU_FUNC_DESC
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "usb_strings_generated.h"
|
void set_usb_serial_str(void)
|
||||||
|
|
||||||
#if 0
|
|
||||||
void set_usb_serial_str(const uint8_t *serial_usbstr)
|
|
||||||
{
|
{
|
||||||
usb_strings[STR_SERIAL] = serial_usbstr;
|
unsigned int i;
|
||||||
}
|
|
||||||
|
// put device ID into USB serial number description
|
||||||
|
unsigned int device_id[4];
|
||||||
|
EEFC_ReadUniqueID(device_id);
|
||||||
|
char device_id_string[32 + 1];
|
||||||
|
snprintf(device_id_string, ARRAY_SIZE(device_id_string), "%08x%08x%08x%08x",
|
||||||
|
device_id[0], device_id[1], device_id[2], device_id[3]);
|
||||||
|
for (i = 0; i < ARRAY_SIZE(device_id_string) - 1; i++) {
|
||||||
|
usb_string_serial[2 + 2 * i] = device_id_string[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// put version into USB string
|
||||||
|
usb_string_version[0] = USBStringDescriptor_LENGTH(ARRAY_SIZE(git_version) - 1);
|
||||||
|
usb_string_version[1] = USBGenericDescriptor_STRING;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(git_version) - 1; i++) {
|
||||||
|
usb_string_version[2 + i * 2 + 0] = git_version[i];
|
||||||
|
usb_string_version[2 + i * 2 + 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill extended USB strings
|
||||||
|
for (i = 0; i < ARRAY_SIZE(usb_strings) && i < ARRAY_SIZE(usb_strings_extended); i++) {
|
||||||
|
usb_strings_extended[i] = usb_strings[i];
|
||||||
|
}
|
||||||
|
#if defined(ENVIRONMENT_dfu)
|
||||||
|
usb_strings_extended[_STR_FIRST_ALT + 1] = usb_string_notavailable;
|
||||||
|
#elif defined(ENVIRONMENT_flash)
|
||||||
|
usb_strings_extended[_STR_FIRST_ALT + 2] = usb_string_notavailable;
|
||||||
#endif
|
#endif
|
||||||
|
usb_strings_extended[STR_SERIAL] = usb_string_serial;
|
||||||
|
usb_strings_extended[VERSION_CONF_STR] = usb_string_version_conf;
|
||||||
|
usb_strings_extended[VERSION_STR] = usb_string_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USB descriptor just to show the version */
|
||||||
|
typedef struct _SIMTraceDriverConfigurationDescriptorVersion {
|
||||||
|
/** Standard configuration descriptor. */
|
||||||
|
USBConfigurationDescriptor configuration;
|
||||||
|
USBInterfaceDescriptor version;
|
||||||
|
} __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptorVersion;
|
||||||
|
|
||||||
|
static const SIMTraceDriverConfigurationDescriptorVersion
|
||||||
|
configurationDescriptorVersion = {
|
||||||
|
/* Standard configuration descriptor for the interface descriptor*/
|
||||||
|
.configuration = {
|
||||||
|
.bLength = sizeof(USBConfigurationDescriptor),
|
||||||
|
.bDescriptorType = USBGenericDescriptor_CONFIGURATION,
|
||||||
|
.wTotalLength = sizeof(SIMTraceDriverConfigurationDescriptorVersion),
|
||||||
|
.bNumInterfaces = 1,
|
||||||
|
.bConfigurationValue = 2,
|
||||||
|
.iConfiguration = VERSION_CONF_STR,
|
||||||
|
.bmAttributes = USBD_BMATTRIBUTES,
|
||||||
|
.bMaxPower = USBConfigurationDescriptor_POWER(100),
|
||||||
|
},
|
||||||
|
/* Interface standard descriptor just holding the version information */
|
||||||
|
.version = {
|
||||||
|
.bLength = sizeof(USBInterfaceDescriptor),
|
||||||
|
.bDescriptorType = USBGenericDescriptor_INTERFACE,
|
||||||
|
.bInterfaceNumber = 0,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 0,
|
||||||
|
.bInterfaceClass = USB_CLASS_PROPRIETARY,
|
||||||
|
.bInterfaceSubClass = 0xff,
|
||||||
|
.bInterfaceProtocol = 0,
|
||||||
|
.iInterface = VERSION_STR,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static const USBConfigurationDescriptor *conf_desc_arr[] = {
|
static const USBConfigurationDescriptor *conf_desc_arr[] = {
|
||||||
&dfu_cfg_descriptor.ucfg,
|
&dfu_cfg_descriptor.ucfg,
|
||||||
|
&configurationDescriptorVersion.configuration,
|
||||||
};
|
};
|
||||||
|
|
||||||
const USBDDriverDescriptors dfu_descriptors = {
|
const USBDDriverDescriptors dfu_descriptors = {
|
||||||
@@ -108,6 +259,6 @@ const USBDDriverDescriptors dfu_descriptors = {
|
|||||||
.pHsConfiguration = NULL,
|
.pHsConfiguration = NULL,
|
||||||
.pHsQualifier = NULL,
|
.pHsQualifier = NULL,
|
||||||
.pHsOtherSpeed = NULL,
|
.pHsOtherSpeed = NULL,
|
||||||
.pStrings = usb_strings,
|
.pStrings = usb_strings_extended,
|
||||||
.numStrings = ARRAY_SIZE(usb_strings),
|
.numStrings = ARRAY_SIZE(usb_strings_extended),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,8 +33,7 @@
|
|||||||
#include <usb/common/dfu/usb_dfu.h>
|
#include <usb/common/dfu/usb_dfu.h>
|
||||||
#include <usb/device/dfu/dfu.h>
|
#include <usb/device/dfu/dfu.h>
|
||||||
|
|
||||||
/* FIXME: this was used for a special ELF section which then got called
|
/** specific memory location shared across bootloader and application */
|
||||||
* by DFU code and Application code, across flash partitions */
|
|
||||||
#define __dfudata __attribute__ ((section (".dfudata")))
|
#define __dfudata __attribute__ ((section (".dfudata")))
|
||||||
#define __dfufunc
|
#define __dfufunc
|
||||||
|
|
||||||
@@ -42,11 +41,14 @@
|
|||||||
static USBDDriver usbdDriver;
|
static USBDDriver usbdDriver;
|
||||||
static unsigned char if_altsettings[1];
|
static unsigned char if_altsettings[1];
|
||||||
|
|
||||||
|
/** structure containing the DFU state and magic value to know if DFU or application should be started */
|
||||||
__dfudata struct dfudata _g_dfu = {
|
__dfudata struct dfudata _g_dfu = {
|
||||||
.state = DFU_STATE_appIDLE,
|
.state = DFU_STATE_dfuIDLE,
|
||||||
.past_manifest = 0,
|
.past_manifest = 0,
|
||||||
.total_bytes = 0,
|
.total_bytes = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** variable to structure containing DFU state */
|
||||||
struct dfudata *g_dfu = &_g_dfu;
|
struct dfudata *g_dfu = &_g_dfu;
|
||||||
|
|
||||||
WEAK void dfu_drv_updstatus(void)
|
WEAK void dfu_drv_updstatus(void)
|
||||||
@@ -83,7 +85,7 @@ static void __dfufunc handle_getstate(void)
|
|||||||
{
|
{
|
||||||
uint8_t u8 = g_dfu->state;
|
uint8_t u8 = g_dfu->state;
|
||||||
|
|
||||||
TRACE_DEBUG("handle_getstate(%u)\n\r", g_dfu->state);
|
TRACE_DEBUG("handle_getstate(%ld)\n\r", g_dfu->state);
|
||||||
|
|
||||||
USBD_Write(0, (char *)&u8, sizeof(u8), NULL, 0);
|
USBD_Write(0, (char *)&u8, sizeof(u8), NULL, 0);
|
||||||
}
|
}
|
||||||
@@ -447,6 +449,7 @@ void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors)
|
|||||||
/* We already start in DFU idle mode */
|
/* We already start in DFU idle mode */
|
||||||
g_dfu->state = DFU_STATE_dfuIDLE;
|
g_dfu->state = DFU_STATE_dfuIDLE;
|
||||||
|
|
||||||
|
set_usb_serial_str();
|
||||||
USBDDriver_Initialize(&usbdDriver, pDescriptors, if_altsettings);
|
USBDDriver_Initialize(&usbdDriver, pDescriptors, if_altsettings);
|
||||||
USBD_Init();
|
USBD_Init();
|
||||||
USBD_Connect();
|
USBD_Connect();
|
||||||
@@ -460,7 +463,20 @@ void USBDFU_SwitchToApp(void)
|
|||||||
/* make sure the MAGIC is not set to enter DFU again */
|
/* make sure the MAGIC is not set to enter DFU again */
|
||||||
g_dfu->magic = 0;
|
g_dfu->magic = 0;
|
||||||
|
|
||||||
printf("switching to app\r\n");
|
/* disconnect from USB to ensure re-enumeration */
|
||||||
|
USBD_Disconnect();
|
||||||
|
|
||||||
|
/* disable any interrupts during transition */
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
|
/* Tell the hybrid to execute FTL JUMP! */
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDFU_SwitchToDFU(void)
|
||||||
|
{
|
||||||
|
/* make sure the MAGIC is not set to enter DFU again */
|
||||||
|
g_dfu->magic = USB_DFU_MAGIC;
|
||||||
|
|
||||||
/* disconnect from USB to ensure re-enumeration */
|
/* disconnect from USB to ensure re-enumeration */
|
||||||
USBD_Disconnect();
|
USBD_Disconnect();
|
||||||
|
|||||||
@@ -36,7 +36,12 @@
|
|||||||
#include <usb/common/dfu/usb_dfu.h>
|
#include <usb/common/dfu/usb_dfu.h>
|
||||||
#include <usb/device/dfu/dfu.h>
|
#include <usb/device/dfu/dfu.h>
|
||||||
|
|
||||||
struct dfudata *g_dfu = (struct dfudata *) IRAM_ADDR;
|
/** specific memory location shared across bootloader and application */
|
||||||
|
#define __dfudata __attribute__ ((section (".dfudata")))
|
||||||
|
/** structure containing the magic value to know if DFU or application should be started */
|
||||||
|
__dfudata struct dfudata _g_dfu;
|
||||||
|
/** variable to structure containing the magic value to know if DFU or application should be started */
|
||||||
|
struct dfudata *g_dfu = &_g_dfu;
|
||||||
|
|
||||||
/* FIXME: this was used for a special ELF section which then got called
|
/* FIXME: this was used for a special ELF section which then got called
|
||||||
* by DFU code and Application code, across flash partitions */
|
* by DFU code and Application code, across flash partitions */
|
||||||
@@ -63,7 +68,7 @@ static void __dfufunc handle_getstate(void)
|
|||||||
{
|
{
|
||||||
uint8_t u8 = g_dfu->state;
|
uint8_t u8 = g_dfu->state;
|
||||||
|
|
||||||
TRACE_DEBUG("handle_getstate(%u)\n\r", g_dfu->state);
|
TRACE_DEBUG("handle_getstate(%lu)\n\r", g_dfu->state);
|
||||||
|
|
||||||
USBD_Write(0, (char *)&u8, sizeof(u8), NULL, 0);
|
USBD_Write(0, (char *)&u8, sizeof(u8), NULL, 0);
|
||||||
}
|
}
|
||||||
@@ -208,7 +213,7 @@ void DFURT_SwitchToDFU(void)
|
|||||||
* activate itself, rather than boot into the application */
|
* activate itself, rather than boot into the application */
|
||||||
g_dfu->magic = USB_DFU_MAGIC;
|
g_dfu->magic = USB_DFU_MAGIC;
|
||||||
|
|
||||||
/* Disconnect the USB by remoting the pull-up */
|
/* Disconnect the USB by removing the pull-up */
|
||||||
USBD_Disconnect();
|
USBD_Disconnect();
|
||||||
__disable_irq();
|
__disable_irq();
|
||||||
|
|
||||||
|
|||||||
@@ -214,6 +214,8 @@ typedef void (*MblTransferCallback)(void *pArg,
|
|||||||
* Exported functions
|
* Exported functions
|
||||||
*------------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern uint16_t USBD_GetEndpointSize(uint8_t bEndpoint);
|
||||||
|
|
||||||
//extern void USBD_IrqHandler(void);
|
//extern void USBD_IrqHandler(void);
|
||||||
|
|
||||||
extern void USBD_Init(void);
|
extern void USBD_Init(void);
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/* SIMtrace 2 common board pin definitions
|
||||||
|
*
|
||||||
|
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* (C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#ifndef _BOARD_
|
#ifndef _BOARD_
|
||||||
#define _BOARD_
|
#define _BOARD_
|
||||||
|
|
||||||
@@ -37,18 +56,12 @@
|
|||||||
/** Core definition */
|
/** Core definition */
|
||||||
#define cortexm3
|
#define cortexm3
|
||||||
|
|
||||||
#define BOARD_MCK 48000000
|
/* LEDs are used to indicate the status
|
||||||
|
* the LED definition is board specific
|
||||||
#define PIO_LED_RED PIO_PA17
|
* most boards have two LEDs, one green and one red
|
||||||
#define PIO_LED_GREEN PIO_PA17
|
* the red LED indicates of the main firmware is ready (on) or if there is an error (blinking)
|
||||||
|
* the green LED indicates if the firmware is idling (on) or if there is activity (blinking)
|
||||||
#define PIN_LED_RED {PIO_LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
*/
|
||||||
#define PIN_LED_GREEN {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
|
||||||
#define PINS_LEDS PIN_LED_RED, PIN_LED_GREEN
|
|
||||||
|
|
||||||
#define LED_NUM_RED 0
|
|
||||||
#define LED_NUM_GREEN 1
|
|
||||||
|
|
||||||
/** USART0 pin RX */
|
/** USART0 pin RX */
|
||||||
#define PIN_USART0_RXD {PIO_PA9A_URXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
#define PIN_USART0_RXD {PIO_PA9A_URXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
/** USART0 pin TX */
|
/** USART0 pin TX */
|
||||||
@@ -63,8 +76,8 @@
|
|||||||
#define PINS_UART { PIO_PA9A_URXD0|PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
#define PINS_UART { PIO_PA9A_URXD0|PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
|
||||||
/** UART0 */
|
/** UART0 */
|
||||||
/** Console baudrate always using 115200. */
|
/** Console baud rate in bps */
|
||||||
#define CONSOLE_BAUDRATE 115200
|
#define CONSOLE_BAUDRATE 921600
|
||||||
/** UART peripheral used by the console (UART0). */
|
/** UART peripheral used by the console (UART0). */
|
||||||
#define CONSOLE_UART UART0
|
#define CONSOLE_UART UART0
|
||||||
/** UART peripheral ID used by the console (UART0). */
|
/** UART peripheral ID used by the console (UART0). */
|
||||||
@@ -81,44 +94,31 @@
|
|||||||
#define BOARD_ISO7816_BASE_USART USART0
|
#define BOARD_ISO7816_BASE_USART USART0
|
||||||
#define BOARD_ISO7816_ID_USART ID_USART0
|
#define BOARD_ISO7816_ID_USART ID_USART0
|
||||||
|
|
||||||
|
/* USART peripherals for a phone and SIM card setup */
|
||||||
|
/* USART peripheral connected to the SIM card */
|
||||||
#define USART_SIM USART0
|
#define USART_SIM USART0
|
||||||
|
/* ID of USART peripheral connected to the SIM card */
|
||||||
#define ID_USART_SIM ID_USART0
|
#define ID_USART_SIM ID_USART0
|
||||||
#define USART_PHONE USART1
|
/* Interrupt request ID of USART peripheral connected to the SIM card */
|
||||||
#define ID_USART_PHONE ID_USART1
|
#define IRQ_USART_SIM USART0_IRQn
|
||||||
|
/* USART peripheral connected to the phone */
|
||||||
#define SIM_PWEN PIO_PA5
|
#define USART_PHONE USART1
|
||||||
#define VCC_FWD PIO_PA26
|
/* ID of USART peripheral connected to the phone */
|
||||||
|
#define ID_USART_PHONE ID_USART1
|
||||||
/** Pin configuration to control USB pull-up on D+
|
/* Interrupt request ID of USART peripheral connected to the phone */
|
||||||
* @details the USB pull-up on D+ is enable by default on the board but can be disabled by setting PA16 high
|
#define IRQ_USART_PHONE USART1_IRQn
|
||||||
*/
|
|
||||||
#define PIN_USB_PULLUP {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
|
||||||
|
|
||||||
// Board has UDP controller
|
// Board has UDP controller
|
||||||
#define BOARD_USB_UDP
|
#define BOARD_USB_UDP
|
||||||
// D+ has external pull-up
|
|
||||||
#define BOARD_USB_PULLUP_EXTERNAL
|
|
||||||
|
|
||||||
#define BOARD_USB_NUMENDPOINTS 8
|
|
||||||
|
|
||||||
// FIXME: in all other cases return 0?
|
|
||||||
#define BOARD_USB_ENDPOINTS_MAXPACKETSIZE(i) (((i == 4) || (i == 5))? 512 : 64)
|
|
||||||
#define BOARD_USB_ENDPOINTS_BANKS(i) (((i == 0) || (i == 3)) ? 1 : 2)
|
|
||||||
|
|
||||||
#define USB_VENDOR_OPENMOKO 0x1d50
|
|
||||||
#define USB_PRODUCT_OWHW_SAM3_DFU 0x4001 /* was 0x4000 */
|
|
||||||
#define USB_PRODUCT_OWHW_SAM3 0x4001
|
|
||||||
#define USB_PRODUCT_QMOD_HUB 0x4002
|
|
||||||
#define USB_PRODUCT_QMOD_SAM3_DFU 0x4004 /* was 0x4003 */
|
|
||||||
#define USB_PRODUCT_QMOD_SAM3 0x4004
|
|
||||||
#define USB_PRODUCT_SIMTRACE2_DFU 0x60e3 /* was 0x60e2 */
|
|
||||||
#define USB_PRODUCT_SIMTRACE2 0x60e3
|
|
||||||
|
|
||||||
#define BOARD_USB_DFU
|
#define BOARD_USB_DFU
|
||||||
|
|
||||||
|
|
||||||
#define BOARD_DFU_BOOT_SIZE (16 * 1024)
|
#define BOARD_DFU_BOOT_SIZE (16 * 1024)
|
||||||
#define BOARD_DFU_RAM_SIZE (2 * 1024)
|
#define BOARD_DFU_RAM_SIZE (2 * 1024)
|
||||||
#define BOARD_DFU_PAGE_SIZE 512
|
#define BOARD_DFU_PAGE_SIZE 512
|
||||||
#define BOARD_DFU_NUM_IF 2
|
/** number of DFU interfaces (used to flash specific partitions) */
|
||||||
|
#define BOARD_DFU_NUM_IF 3
|
||||||
|
|
||||||
extern void board_exec_dbg_cmd(int ch);
|
extern void board_exec_dbg_cmd(int ch);
|
||||||
extern void board_main_top(void);
|
extern void board_main_top(void);
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,3 +1,18 @@
|
|||||||
|
/* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int get_board_version_adc(void);
|
int get_board_version_adc(void);
|
||||||
|
uint32_t adc2uv(uint16_t adc);
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
/* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
enum led {
|
enum led {
|
||||||
@@ -13,9 +27,11 @@ enum led_pattern {
|
|||||||
BLINK_3O_30F = 3,
|
BLINK_3O_30F = 3,
|
||||||
BLINK_3O_1F_3O_30F = 4,
|
BLINK_3O_1F_3O_30F = 4,
|
||||||
BLINK_3O_1F_3O_1F_3O_30F= 5,
|
BLINK_3O_1F_3O_1F_3O_30F= 5,
|
||||||
BLINK_200O_F = 6,
|
BLINK_2O_F = 6,
|
||||||
BLINK_600O_F = 7,
|
BLINK_200O_F = 7,
|
||||||
BLINK_CUSTOM = 8,
|
BLINK_600O_F = 8,
|
||||||
|
BLINK_CUSTOM = 9,
|
||||||
|
BLINK_2F_O,
|
||||||
_NUM_LED_BLINK
|
_NUM_LED_BLINK
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,17 @@
|
|||||||
|
/* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#ifndef _MANIFEST_H
|
#ifndef _MANIFEST_H
|
||||||
#define _MANIFEST_H
|
#define _MANIFEST_H
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
/* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int sim_switch_use_physical(unsigned int nr, int physical);
|
int sim_switch_use_physical(unsigned int nr, int physical);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* ATMEL Microcontroller Software Support
|
* ATMEL Microcontroller Software Support
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2009, Atmel Corporation
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
* Copyright (c) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -26,19 +27,17 @@
|
|||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _UART_CONSOLE_
|
#ifndef _UART_CONSOLE_
|
||||||
#define _UART_CONSOLE_
|
#define _UART_CONSOLE_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
extern void UART_Configure( uint32_t dwBaudrate, uint32_t dwMasterClock ) ;
|
extern void UART_Configure( uint32_t dwBaudrate, uint32_t dwMasterClock ) ;
|
||||||
|
extern void UART_Exit( void ) ;
|
||||||
extern void UART_PutChar( uint8_t uc ) ;
|
extern void UART_PutChar( uint8_t uc ) ;
|
||||||
|
extern void UART_PutChar_Sync( uint8_t uc ) ;
|
||||||
extern uint32_t UART_GetChar( void ) ;
|
extern uint32_t UART_GetChar( void ) ;
|
||||||
extern uint32_t UART_IsRxReady( void ) ;
|
extern uint32_t UART_IsRxReady( void ) ;
|
||||||
|
|
||||||
|
|
||||||
extern void UART_DumpFrame( uint8_t* pucFrame, uint32_t dwSize ) ;
|
extern void UART_DumpFrame( uint8_t* pucFrame, uint32_t dwSize ) ;
|
||||||
extern void UART_DumpMemory( uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress ) ;
|
extern void UART_DumpMemory( uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress ) ;
|
||||||
extern uint32_t UART_GetInteger( uint32_t* pdwValue ) ;
|
extern uint32_t UART_GetInteger( uint32_t* pdwValue ) ;
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ SEARCH_DIR(.)
|
|||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
/* reserve the first 16k (= 0x4000) for the DFU bootloader */
|
/* reserve the first 16k (= 0x4000) for the DFU bootloader */
|
||||||
rom (rx) : ORIGIN = 0x00404000, LENGTH = 0x0003c000 /* flash, 256K */
|
rom (rx) : ORIGIN = 0x00400000 + 16K, LENGTH = 256K - 16K /* flash, 256K */
|
||||||
/* reserve the first 32 (= 0x20) bytes for the _g_dfu struct */
|
/* note: dfudata will be at the start */
|
||||||
ram (rwx) : ORIGIN = 0x20000020, LENGTH = 0x0000bfe0 /* sram, 48K */
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K /* SRAM, 48K */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Section Definitions */
|
/* Section Definitions */
|
||||||
@@ -111,6 +111,8 @@ SECTIONS
|
|||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_srelocate = .;
|
_srelocate = .;
|
||||||
|
/* we must make sure the .dfudata is linked to start of RAM */
|
||||||
|
*(.dfudata .dfudata.*);
|
||||||
*(.ramfunc .ramfunc.*);
|
*(.ramfunc .ramfunc.*);
|
||||||
*(.data .data.*);
|
*(.data .data.*);
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ SEARCH_DIR(.)
|
|||||||
/* Memory Spaces Definitions */
|
/* Memory Spaces Definitions */
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00040000 /* flash, 256K */
|
rom (rx) : ORIGIN = 0x00400000, LENGTH = 16K /* flash, 256K, but only the first 16K should be used for the bootloader */
|
||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0000c000 /* sram, 48K */
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K /* SRAM, 48K */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Section Definitions */
|
/* Section Definitions */
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
* ATMEL Microcontroller Software Support
|
* ATMEL Microcontroller Software Support
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2010, Atmel Corporation
|
* Copyright (c) 2010, Atmel Corporation
|
||||||
* Copyright (C) 2017, Harald Welte <laforge@gnumonks.org>
|
* Copyright (c) 2017, Harald Welte <laforge@gnumonks.org>
|
||||||
|
* Copyright (c) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -70,62 +71,62 @@ void ResetException( void ) ;
|
|||||||
__attribute__((section(".vectors")))
|
__attribute__((section(".vectors")))
|
||||||
IntFunc exception_table[] = {
|
IntFunc exception_table[] = {
|
||||||
|
|
||||||
/* Configure Initial Stack Pointer, using linker-generated symbols */
|
/* Configure Initial Stack Pointer, using linker-generated symbols */
|
||||||
(IntFunc)(&pdwStack[STACK_SIZE-1]),
|
(IntFunc)(&pdwStack[STACK_SIZE-1]),
|
||||||
ResetException,
|
ResetException,
|
||||||
|
|
||||||
NMI_Handler,
|
NMI_Handler,
|
||||||
HardFault_Handler,
|
HardFault_Handler,
|
||||||
MemManage_Handler,
|
MemManage_Handler,
|
||||||
BusFault_Handler,
|
BusFault_Handler,
|
||||||
UsageFault_Handler,
|
UsageFault_Handler,
|
||||||
0, 0, 0, 0, /* Reserved */
|
0, 0, 0, 0, /* Reserved */
|
||||||
SVC_Handler,
|
SVC_Handler,
|
||||||
DebugMon_Handler,
|
DebugMon_Handler,
|
||||||
0, /* Reserved */
|
0, /* Reserved */
|
||||||
PendSV_Handler,
|
PendSV_Handler,
|
||||||
SysTick_Handler,
|
SysTick_Handler,
|
||||||
|
|
||||||
/* Configurable interrupts */
|
/* Configurable interrupts */
|
||||||
SUPC_IrqHandler, /* 0 Supply Controller */
|
SUPC_IrqHandler, /* 0 Supply Controller */
|
||||||
RSTC_IrqHandler, /* 1 Reset Controller */
|
RSTC_IrqHandler, /* 1 Reset Controller */
|
||||||
RTC_IrqHandler, /* 2 Real Time Clock */
|
RTC_IrqHandler, /* 2 Real Time Clock */
|
||||||
RTT_IrqHandler, /* 3 Real Time Timer */
|
RTT_IrqHandler, /* 3 Real Time Timer */
|
||||||
WDT_IrqHandler, /* 4 Watchdog Timer */
|
WDT_IrqHandler, /* 4 Watchdog Timer */
|
||||||
PMC_IrqHandler, /* 5 PMC */
|
PMC_IrqHandler, /* 5 PMC */
|
||||||
EEFC_IrqHandler, /* 6 EEFC */
|
EEFC_IrqHandler, /* 6 EEFC */
|
||||||
IrqHandlerNotUsed, /* 7 Reserved */
|
IrqHandlerNotUsed, /* 7 Reserved */
|
||||||
UART0_IrqHandler, /* 8 UART0 */
|
UART0_IrqHandler, /* 8 UART0 */
|
||||||
UART1_IrqHandler, /* 9 UART1 */
|
UART1_IrqHandler, /* 9 UART1 */
|
||||||
SMC_IrqHandler, /* 10 SMC */
|
SMC_IrqHandler, /* 10 SMC */
|
||||||
PIOA_IrqHandler, /* 11 Parallel IO Controller A */
|
PIOA_IrqHandler, /* 11 Parallel IO Controller A */
|
||||||
PIOB_IrqHandler, /* 12 Parallel IO Controller B */
|
PIOB_IrqHandler, /* 12 Parallel IO Controller B */
|
||||||
PIOC_IrqHandler, /* 13 Parallel IO Controller C */
|
PIOC_IrqHandler, /* 13 Parallel IO Controller C */
|
||||||
USART0_IrqHandler, /* 14 USART 0 */
|
USART0_IrqHandler, /* 14 USART 0 */
|
||||||
USART1_IrqHandler, /* 15 USART 1 */
|
USART1_IrqHandler, /* 15 USART 1 */
|
||||||
IrqHandlerNotUsed, /* 16 Reserved */
|
IrqHandlerNotUsed, /* 16 Reserved */
|
||||||
IrqHandlerNotUsed, /* 17 Reserved */
|
IrqHandlerNotUsed, /* 17 Reserved */
|
||||||
MCI_IrqHandler, /* 18 MCI */
|
MCI_IrqHandler, /* 18 MCI */
|
||||||
TWI0_IrqHandler, /* 19 TWI 0 */
|
TWI0_IrqHandler, /* 19 TWI 0 */
|
||||||
TWI1_IrqHandler, /* 20 TWI 1 */
|
TWI1_IrqHandler, /* 20 TWI 1 */
|
||||||
SPI_IrqHandler, /* 21 SPI */
|
SPI_IrqHandler, /* 21 SPI */
|
||||||
SSC_IrqHandler, /* 22 SSC */
|
SSC_IrqHandler, /* 22 SSC */
|
||||||
TC0_IrqHandler, /* 23 Timer Counter 0 */
|
TC0_IrqHandler, /* 23 Timer Counter 0 */
|
||||||
TC1_IrqHandler, /* 24 Timer Counter 1 */
|
TC1_IrqHandler, /* 24 Timer Counter 1 */
|
||||||
TC2_IrqHandler, /* 25 Timer Counter 2 */
|
TC2_IrqHandler, /* 25 Timer Counter 2 */
|
||||||
TC3_IrqHandler, /* 26 Timer Counter 3 */
|
TC3_IrqHandler, /* 26 Timer Counter 3 */
|
||||||
TC4_IrqHandler, /* 27 Timer Counter 4 */
|
TC4_IrqHandler, /* 27 Timer Counter 4 */
|
||||||
TC5_IrqHandler, /* 28 Timer Counter 5 */
|
TC5_IrqHandler, /* 28 Timer Counter 5 */
|
||||||
ADC_IrqHandler, /* 29 ADC controller */
|
ADC_IrqHandler, /* 29 ADC controller */
|
||||||
DAC_IrqHandler, /* 30 DAC controller */
|
DAC_IrqHandler, /* 30 DAC controller */
|
||||||
PWM_IrqHandler, /* 31 PWM */
|
PWM_IrqHandler, /* 31 PWM */
|
||||||
CRCCU_IrqHandler, /* 32 CRC Calculation Unit */
|
CRCCU_IrqHandler, /* 32 CRC Calculation Unit */
|
||||||
ACC_IrqHandler, /* 33 Analog Comparator */
|
ACC_IrqHandler, /* 33 Analog Comparator */
|
||||||
USBD_IrqHandler, /* 34 USB Device Port */
|
USBD_IrqHandler, /* 34 USB Device Port */
|
||||||
IrqHandlerNotUsed /* 35 not used */
|
IrqHandlerNotUsed /* 35 not used */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
|
#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu) && defined(ENVIRONMENT_flash)
|
||||||
#include "usb/device/dfu/dfu.h"
|
#include "usb/device/dfu/dfu.h"
|
||||||
static void BootIntoApp(void)
|
static void BootIntoApp(void)
|
||||||
{
|
{
|
||||||
@@ -133,7 +134,11 @@ static void BootIntoApp(void)
|
|||||||
void (*appReset)(void);
|
void (*appReset)(void);
|
||||||
|
|
||||||
pSrc = (unsigned int *) ((unsigned char *)IFLASH_ADDR + BOARD_DFU_BOOT_SIZE);
|
pSrc = (unsigned int *) ((unsigned char *)IFLASH_ADDR + BOARD_DFU_BOOT_SIZE);
|
||||||
SCB->VTOR = ((unsigned int)(pSrc)) | (0x0 << 7);
|
/* set vector table to application vector table (store at the beginning of the application) */
|
||||||
|
SCB->VTOR = (unsigned int)(pSrc);
|
||||||
|
/* set stack pointer to address provided in the beginning of the application (loaded into a register first) */
|
||||||
|
__asm__ volatile ("MSR msp,%0" : :"r"(*pSrc));
|
||||||
|
/* start application (by jumping to the reset function which address is stored as second entry of the vector table) */
|
||||||
appReset = (void(*)(void))pSrc[1];
|
appReset = (void(*)(void))pSrc[1];
|
||||||
|
|
||||||
g_dfu->state = DFU_STATE_appIDLE;
|
g_dfu->state = DFU_STATE_appIDLE;
|
||||||
@@ -148,68 +153,57 @@ static void BootIntoApp(void)
|
|||||||
*/
|
*/
|
||||||
void ResetException( void )
|
void ResetException( void )
|
||||||
{
|
{
|
||||||
uint32_t *pSrc, *pDest ;
|
uint32_t *pSrc, *pDest ;
|
||||||
|
|
||||||
/* Low level Initialize */
|
/* Low level Initialize */
|
||||||
LowLevelInit() ;
|
LowLevelInit() ;
|
||||||
|
|
||||||
|
|
||||||
#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
|
#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu) && defined(ENVIRONMENT_flash)
|
||||||
/* we are before the text segment has been relocated, so g_dfu is
|
// boot application if there is not DFU override
|
||||||
* not initialized yet */
|
if (!USBDFU_OverrideEnterDFU() && SCB->VTOR < IFLASH_ADDR + BOARD_DFU_BOOT_SIZE) {
|
||||||
g_dfu = &_g_dfu;
|
UART_Exit();
|
||||||
if ((g_dfu->magic != USB_DFU_MAGIC) && !USBDFU_OverrideEnterDFU()) {
|
__disable_irq();
|
||||||
/* start application if valid
|
BootIntoApp();
|
||||||
* the application starts with the vector table
|
/* Infinite loop */
|
||||||
* the first entry in the vector table is the initial stack pointer (SP) address
|
while ( 1 ) ;
|
||||||
* the stack will be placed in RAM, which begins at 0x2000 0000
|
}
|
||||||
* there is up to 48 KB of RAM (0xc000)
|
|
||||||
* since the stack grown "downwards" it should start at the end of the RAM: max 0x2000 c000
|
|
||||||
* if the SP is not in this range (e.g. flash has been erased) there is no valid application
|
|
||||||
* the second entry in the vector table is the reset address, corresponding to the application start
|
|
||||||
*/
|
|
||||||
if (((*((uint32_t*)(IFLASH_ADDR+BOARD_DFU_BOOT_SIZE)))&0xFFFF0000)==0x20000000) {
|
|
||||||
BootIntoApp();
|
|
||||||
/* Infinite loop */
|
|
||||||
while ( 1 ) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize the relocate segment */
|
/* Initialize the relocate segment */
|
||||||
pSrc = &_etext ;
|
pSrc = &_etext ;
|
||||||
pDest = &_srelocate ;
|
pDest = &_srelocate ;
|
||||||
|
|
||||||
if ( pSrc != pDest )
|
if ( pSrc != pDest )
|
||||||
{
|
{
|
||||||
for ( ; pDest < &_erelocate ; )
|
for ( ; pDest < &_erelocate ; )
|
||||||
{
|
{
|
||||||
*pDest++ = *pSrc++ ;
|
*pDest++ = *pSrc++ ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the zero segment */
|
/* Clear the zero segment */
|
||||||
for ( pDest = &_szero ; pDest < &_ezero ; )
|
for ( pDest = &_szero ; pDest < &_ezero ; )
|
||||||
{
|
{
|
||||||
*pDest++ = 0;
|
*pDest++ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the vector table base address */
|
/* Set the vector table base address */
|
||||||
pSrc = (uint32_t *)&_sfixed;
|
pSrc = (uint32_t *)&_sfixed;
|
||||||
SCB->VTOR = ( (uint32_t)pSrc & SCB_VTOR_TBLOFF_Msk ) ;
|
SCB->VTOR = ( (uint32_t)pSrc & SCB_VTOR_TBLOFF_Msk ) ;
|
||||||
|
|
||||||
if ( ((uint32_t)pSrc >= IRAM_ADDR) && ((uint32_t)pSrc < IRAM_ADDR+IRAM_SIZE) )
|
if ( ((uint32_t)pSrc >= IRAM_ADDR) && ((uint32_t)pSrc < IRAM_ADDR+IRAM_SIZE) )
|
||||||
{
|
{
|
||||||
SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos ;
|
SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* App should have disabled interrupts during the transition */
|
/* App should have disabled interrupts during the transition */
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
/* Branch to main function */
|
/* Branch to main function */
|
||||||
main() ;
|
main() ;
|
||||||
|
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* ATMEL Microcontroller Software Support
|
* ATMEL Microcontroller Software Support
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2009, Atmel Corporation
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
* Copyright (c) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -46,39 +47,39 @@
|
|||||||
#define BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8))
|
#define BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8))
|
||||||
#define BOARD_MCKR (PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)
|
#define BOARD_MCKR (PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)
|
||||||
|
|
||||||
#if (BOARD_MCK == 48000000)
|
/** configure PLL to generate main clock based on main oscillator frequency */
|
||||||
#if (BOARD_MAINOSC == 18432000)
|
#if (BOARD_MAINOSC == 12000000) && (BOARD_MCK == 48000000)
|
||||||
/* Clock settings at 48MHz for 18 MHz crystal */
|
|
||||||
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||||
| CKGR_PLLAR_MULA(13-1) \
|
| CKGR_PLLAR_MULA(8-1) \
|
||||||
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||||
| CKGR_PLLAR_DIVA(5))
|
| CKGR_PLLAR_DIVA(2))
|
||||||
#elif (BOARD_MAINOSC == 12000000)
|
#elif (BOARD_MAINOSC == 12000000) && (BOARD_MCK == 58000000)
|
||||||
/* QMod has 12 MHz clock, so multply by 8 (96 MHz) and divide by 2 */
|
|
||||||
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||||
| CKGR_PLLAR_MULA(8-1) \
|
| CKGR_PLLAR_MULA(29-1) \
|
||||||
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||||
| CKGR_PLLAR_DIVA(2))
|
| CKGR_PLLAR_DIVA(6))
|
||||||
|
#elif (BOARD_MAINOSC == 12000000) && (BOARD_MCK == 60000000)
|
||||||
|
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||||
|
| CKGR_PLLAR_MULA(10-1) \
|
||||||
|
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||||
|
| CKGR_PLLAR_DIVA(2))
|
||||||
|
#elif (BOARD_MAINOSC == 18432000) && (BOARD_MCK == 47923200)
|
||||||
|
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||||
|
| CKGR_PLLAR_MULA(13-1) \
|
||||||
|
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||||
|
| CKGR_PLLAR_DIVA(5))
|
||||||
|
#elif (BOARD_MAINOSC == 18432000) && (BOARD_MCK == 58982400)
|
||||||
|
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||||
|
| CKGR_PLLAR_MULA(16-1) \
|
||||||
|
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||||
|
| CKGR_PLLAR_DIVA(5))
|
||||||
|
#elif (BOARD_MAINOSC == 18432000) && (BOARD_MCK == 64512000)
|
||||||
|
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||||
|
| CKGR_PLLAR_MULA(7-1) \
|
||||||
|
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||||
|
| CKGR_PLLAR_DIVA(2))
|
||||||
#else
|
#else
|
||||||
#error "Please define PLLA config for your MAINOSC frequency"
|
#error "Please define PLLA config for your BOARD_MCK/MAINOSC frequency"
|
||||||
#endif /* MAINOSC */
|
|
||||||
#elif (BOARD_MCK == 64000000)
|
|
||||||
#if (BOARD_MAINOSC == 18432000)
|
|
||||||
/* Clock settings at 64MHz for 18 MHz crystal: 64.512 MHz */
|
|
||||||
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
|
||||||
| CKGR_PLLAR_MULA(7-1) \
|
|
||||||
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
|
||||||
| CKGR_PLLAR_DIVA(2))
|
|
||||||
#elif (BOARD_MAINOSC == 12000000)
|
|
||||||
/* QMod has 12 MHz clock, so multply by 10 / div by 2: 60 MHz */
|
|
||||||
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
|
||||||
| CKGR_PLLAR_MULA(10-1) \
|
|
||||||
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
|
||||||
| CKGR_PLLAR_DIVA(2))
|
|
||||||
#error "Please define PLLA config for your MAINOSC frequency"
|
|
||||||
#endif /* MAINOSC */
|
|
||||||
#else
|
|
||||||
#error "No PLL settings for current BOARD_MCK."
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (BOARD_MAINOSC == 12000000)
|
#if (BOARD_MAINOSC == 12000000)
|
||||||
@@ -117,85 +118,88 @@ static void _ConfigureUsbClock(void)
|
|||||||
*/
|
*/
|
||||||
extern WEAK void LowLevelInit( void )
|
extern WEAK void LowLevelInit( void )
|
||||||
{
|
{
|
||||||
uint32_t timeout = 0;
|
uint32_t timeout = 0;
|
||||||
|
|
||||||
/* Configure the Supply Monitor to reset the CPU in case VDDIO is
|
/* Configure the Supply Monitor to reset the CPU in case VDDIO is
|
||||||
* lower than 3.0V. As we run the board on 3.3V, any lower voltage
|
* lower than 3.0V. As we run the board on 3.3V, any lower voltage
|
||||||
* might be some kind of leakage that creeps in some way, but is not
|
* might be some kind of leakage that creeps in some way, but is not
|
||||||
* the "official" power supply */
|
* the "official" power supply */
|
||||||
SUPC->SUPC_SMMR = SUPC_SMMR_SMTH_3_0V | SUPC_SMMR_SMSMPL_CSM |
|
SUPC->SUPC_SMMR = SUPC_SMMR_SMTH_3_0V | SUPC_SMMR_SMSMPL_CSM |
|
||||||
SUPC_SMMR_SMRSTEN_ENABLE;
|
SUPC_SMMR_SMRSTEN_ENABLE;
|
||||||
|
|
||||||
/* enable both LED and green LED */
|
/* disable ERASE pin to prevent accidental flash erase */
|
||||||
PIOA->PIO_PER |= PIO_LED_RED | PIO_LED_GREEN;
|
MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO12;
|
||||||
PIOA->PIO_OER |= PIO_LED_RED | PIO_LED_GREEN;
|
|
||||||
PIOA->PIO_CODR |= PIO_LED_RED | PIO_LED_GREEN;
|
|
||||||
|
|
||||||
/* Set 3 FWS for Embedded Flash Access */
|
/* enable both LED and green LED */
|
||||||
EFC->EEFC_FMR = EEFC_FMR_FWS(3);
|
PIOA->PIO_PER |= PIO_LED_RED | PIO_LED_GREEN;
|
||||||
|
PIOA->PIO_OER |= PIO_LED_RED | PIO_LED_GREEN;
|
||||||
|
PIOA->PIO_CODR |= PIO_LED_RED | PIO_LED_GREEN;
|
||||||
|
|
||||||
/* Select external slow clock */
|
/* Set 3 FWS for Embedded Flash Access */
|
||||||
|
EFC->EEFC_FMR = EEFC_FMR_FWS(3);
|
||||||
|
|
||||||
|
/* Select external slow clock */
|
||||||
/* if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST)
|
/* if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST)
|
||||||
{
|
{
|
||||||
SUPC->SUPC_CR = (uint32_t)(SUPC_CR_XTALSEL_CRYSTAL_SEL | SUPC_CR_KEY(0xA5));
|
SUPC->SUPC_CR = (uint32_t)(SUPC_CR_XTALSEL_CRYSTAL_SEL | SUPC_CR_KEY(0xA5));
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL_CRYST) );
|
while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL_CRYST) );
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef qmod
|
#ifndef qmod
|
||||||
/* Initialize main oscillator */
|
/* Initialize main oscillator */
|
||||||
if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )
|
if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )
|
||||||
{
|
{
|
||||||
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
|
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT));
|
while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Switch to 3-20MHz Xtal oscillator */
|
/* Switch to 3-20MHz Xtal oscillator */
|
||||||
PIOB->PIO_PDR = (1 << 8) | (1 << 9);
|
PIOB->PIO_PDR = (1 << 8) | (1 << 9);
|
||||||
PIOB->PIO_PUDR = (1 << 8) | (1 << 9);
|
PIOB->PIO_PUDR = (1 << 8) | (1 << 9);
|
||||||
PIOB->PIO_PPDDR = (1 << 8) | (1 << 9);
|
PIOB->PIO_PPDDR = (1 << 8) | (1 << 9);
|
||||||
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
|
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
|
||||||
/* wait for Main XTAL oscillator stabilization */
|
/* wait for Main XTAL oscillator stabilization */
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT));
|
while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT));
|
||||||
#else
|
#else
|
||||||
/* QMOD has external 12MHz clock source */
|
/* QMOD has external 12MHz clock source */
|
||||||
PIOB->PIO_PDR = (1 << 9);
|
PIOB->PIO_PDR = (1 << 9);
|
||||||
PIOB->PIO_PUDR = (1 << 9);
|
PIOB->PIO_PUDR = (1 << 9);
|
||||||
PIOB->PIO_PPDDR = (1 << 9);
|
PIOB->PIO_PPDDR = (1 << 9);
|
||||||
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTBY| CKGR_MOR_MOSCSEL;
|
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTBY| CKGR_MOR_MOSCSEL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* disable the red LED after main clock initialization */
|
/* disable the red LED after main clock initialization */
|
||||||
PIOA->PIO_SODR = PIO_LED_RED;
|
PIOA->PIO_SODR = PIO_LED_RED;
|
||||||
|
|
||||||
/* "switch" to main clock as master clock source (should already be the case */
|
/* "switch" to main clock as master clock source (should already be the case */
|
||||||
PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
||||||
/* wait for master clock to be ready */
|
/* wait for master clock to be ready */
|
||||||
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
||||||
|
|
||||||
/* Initialize PLLA */
|
/* Initialize PLLA */
|
||||||
PMC->CKGR_PLLAR = BOARD_PLLAR;
|
PMC->CKGR_PLLAR = BOARD_PLLAR;
|
||||||
/* Wait for PLLA to lock */
|
/* Wait for PLLA to lock */
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (timeout++ < CLOCK_TIMEOUT));
|
while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (timeout++ < CLOCK_TIMEOUT));
|
||||||
|
|
||||||
/* Switch to main clock (again ?!?) */
|
/* Switch to main clock (again ?!?) */
|
||||||
PMC->PMC_MCKR = (BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
PMC->PMC_MCKR = (BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
||||||
/* wait for master clock to be ready */
|
/* wait for master clock to be ready */
|
||||||
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
||||||
|
|
||||||
/* switch to PLLA as master clock source */
|
/* switch to PLLA as master clock source */
|
||||||
PMC->PMC_MCKR = BOARD_MCKR ;
|
PMC->PMC_MCKR = BOARD_MCKR ;
|
||||||
/* wait for master clock to be ready */
|
/* wait for master clock to be ready */
|
||||||
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
||||||
|
|
||||||
/* Configure SysTick for 1ms */
|
/* Configure SysTick for 1ms */
|
||||||
SysTick_Config(BOARD_MCK/1000);
|
SysTick_Config(BOARD_MCK/1000);
|
||||||
|
|
||||||
_ConfigureUsbClock();
|
_ConfigureUsbClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SysTick based delay function */
|
/* SysTick based delay function */
|
||||||
|
|||||||
@@ -1,9 +1,22 @@
|
|||||||
|
/* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "boardver_adc.h"
|
#include "boardver_adc.h"
|
||||||
|
|
||||||
/* FIXME: share this with mode_cardemu.c */
|
|
||||||
#define UV_PER_LSB ((3300 * 1000) / 4096)
|
#define UV_PER_LSB ((3300 * 1000) / 4096)
|
||||||
static uint32_t adc2uv(uint16_t adc)
|
uint32_t adc2uv(uint16_t adc)
|
||||||
{
|
{
|
||||||
uint32_t uv = (uint32_t) adc * UV_PER_LSB;
|
uint32_t uv = (uint32_t) adc * UV_PER_LSB;
|
||||||
return uv;
|
return uv;
|
||||||
@@ -73,7 +86,7 @@ int get_board_version_adc(void)
|
|||||||
/* convert to voltage */
|
/* convert to voltage */
|
||||||
sample = ADC->ADC_CDR[2];
|
sample = ADC->ADC_CDR[2];
|
||||||
uv = adc2uv(sample);
|
uv = adc2uv(sample);
|
||||||
TRACE_INFO("VERSION_DET ADC=%u => %u uV\r\n", sample, uv);
|
TRACE_INFO("VERSION_DET ADC=%u => %lu uV\r\n", sample, uv);
|
||||||
|
|
||||||
/* FIXME: convert to board version based on thresholds */
|
/* FIXME: convert to board version based on thresholds */
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/* LED control
|
||||||
|
*
|
||||||
|
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@@ -16,9 +35,9 @@ static void led_set(enum led led, int on)
|
|||||||
ASSERT(led < PIO_LISTSIZE(pinsLeds));
|
ASSERT(led < PIO_LISTSIZE(pinsLeds));
|
||||||
|
|
||||||
if (on)
|
if (on)
|
||||||
PIO_Set(&pinsLeds[led]);
|
PIO_Clear(&pinsLeds[led]);
|
||||||
else
|
else
|
||||||
PIO_Clear(&pinsLeds[led]);
|
PIO_Set(&pinsLeds[led]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LED blinking code */
|
/* LED blinking code */
|
||||||
@@ -27,7 +46,7 @@ static void led_set(enum led led, int on)
|
|||||||
struct blink_state {
|
struct blink_state {
|
||||||
/* duration of the state in ms */
|
/* duration of the state in ms */
|
||||||
uint16_t duration;
|
uint16_t duration;
|
||||||
/* bringhtness of LED during the state */
|
/* brightness of LED during the state */
|
||||||
uint8_t on;
|
uint8_t on;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
@@ -54,13 +73,23 @@ static const struct blink_state bs_3on_1off_3on_30off[] = {
|
|||||||
static const struct blink_state bs_3on_1off_3on_1off_3on_30off[] = {
|
static const struct blink_state bs_3on_1off_3on_1off_3on_30off[] = {
|
||||||
{ 300, 1 }, { 100, 0 }, { 300, 1 }, { 100, 0 }, { 300, 1 }, { 3000, 0 }
|
{ 300, 1 }, { 100, 0 }, { 300, 1 }, { 100, 0 }, { 300, 1 }, { 3000, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct blink_state bs_2on_off[] = {
|
||||||
|
{ 200, 1 }, { 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
static const struct blink_state bs_200on_off[] = {
|
static const struct blink_state bs_200on_off[] = {
|
||||||
{ 20000, 1 }, { 0, 0 },
|
{ 20000, 1 }, { 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct blink_state bs_600on_off[] = {
|
static const struct blink_state bs_600on_off[] = {
|
||||||
{ 60000, 1 }, { 0, 0 },
|
{ 60000, 1 }, { 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct blink_state bs_2off_on[] = {
|
||||||
|
{ 200, 0 }, { 0, 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* a blink pattern is an array of blink_states */
|
/* a blink pattern is an array of blink_states */
|
||||||
struct blink_pattern {
|
struct blink_pattern {
|
||||||
@@ -94,6 +123,10 @@ static const struct blink_pattern patterns[] = {
|
|||||||
.states = bs_3on_1off_3on_1off_3on_30off,
|
.states = bs_3on_1off_3on_1off_3on_30off,
|
||||||
.size = ARRAY_SIZE(bs_3on_1off_3on_1off_3on_30off),
|
.size = ARRAY_SIZE(bs_3on_1off_3on_1off_3on_30off),
|
||||||
},
|
},
|
||||||
|
[BLINK_2O_F] = {
|
||||||
|
.states = bs_2on_off,
|
||||||
|
.size = ARRAY_SIZE(bs_2on_off),
|
||||||
|
},
|
||||||
[BLINK_200O_F] = {
|
[BLINK_200O_F] = {
|
||||||
.states = bs_200on_off,
|
.states = bs_200on_off,
|
||||||
.size = ARRAY_SIZE(bs_200on_off),
|
.size = ARRAY_SIZE(bs_200on_off),
|
||||||
@@ -102,6 +135,11 @@ static const struct blink_pattern patterns[] = {
|
|||||||
.states = bs_600on_off,
|
.states = bs_600on_off,
|
||||||
.size = ARRAY_SIZE(bs_600on_off),
|
.size = ARRAY_SIZE(bs_600on_off),
|
||||||
},
|
},
|
||||||
|
[BLINK_2F_O] = {
|
||||||
|
.states = bs_2off_on,
|
||||||
|
.size = ARRAY_SIZE(bs_2off_on),
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct led_state {
|
struct led_state {
|
||||||
@@ -158,16 +196,16 @@ static void blink_tmr_cb(void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct led_state led_state[] = {
|
static struct led_state led_state[] = {
|
||||||
[LED_GREEN] = {
|
|
||||||
.led = LED_GREEN,
|
|
||||||
.timer.cb = blink_tmr_cb,
|
|
||||||
.timer.data = &led_state[LED_GREEN],
|
|
||||||
},
|
|
||||||
[LED_RED] = {
|
[LED_RED] = {
|
||||||
.led = LED_RED,
|
.led = LED_RED,
|
||||||
.timer.cb = blink_tmr_cb,
|
.timer.cb = blink_tmr_cb,
|
||||||
.timer.data = &led_state[LED_RED],
|
.timer.data = &led_state[LED_RED],
|
||||||
},
|
},
|
||||||
|
[LED_GREEN] = {
|
||||||
|
.led = LED_GREEN,
|
||||||
|
.timer.cb = blink_tmr_cb,
|
||||||
|
.timer.data = &led_state[LED_GREEN],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
#endif /* PINS_LEDS */
|
#endif /* PINS_LEDS */
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,17 @@
|
|||||||
|
/* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#include "manifest.h"
|
#include "manifest.h"
|
||||||
|
|
||||||
const char *manifest_application = APPLICATION;
|
const char *manifest_application = APPLICATION;
|
||||||
|
|||||||
@@ -1,5 +1,21 @@
|
|||||||
/* Code to switch between local (physical) and remote (emulated) SIM */
|
/* Code to switch between local (physical) and remote (emulated) SIM
|
||||||
|
*
|
||||||
|
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* ATMEL Microcontroller Software Support
|
* ATMEL Microcontroller Software Support
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2009, Atmel Corporation
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
* Copyright (c) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -66,41 +67,62 @@ static ringbuf uart_tx_buffer;
|
|||||||
*/
|
*/
|
||||||
extern void UART_Configure( uint32_t baudrate, uint32_t masterClock)
|
extern void UART_Configure( uint32_t baudrate, uint32_t masterClock)
|
||||||
{
|
{
|
||||||
const Pin pPins[] = CONSOLE_PINS;
|
const Pin pPins[] = CONSOLE_PINS;
|
||||||
Uart *pUart = CONSOLE_UART;
|
Uart *pUart = CONSOLE_UART;
|
||||||
|
|
||||||
/* Configure PIO */
|
/* Configure PIO */
|
||||||
PIO_Configure(pPins, PIO_LISTSIZE(pPins));
|
PIO_Configure(pPins, PIO_LISTSIZE(pPins));
|
||||||
|
|
||||||
/* Configure PMC */
|
/* Configure PMC */
|
||||||
PMC->PMC_PCER0 = 1 << CONSOLE_ID;
|
PMC->PMC_PCER0 = 1 << CONSOLE_ID;
|
||||||
|
|
||||||
/* Reset and disable receiver & transmitter */
|
/* Reset and disable receiver & transmitter */
|
||||||
pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
|
pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
|
||||||
| UART_CR_RXDIS | UART_CR_TXDIS;
|
| UART_CR_RXDIS | UART_CR_TXDIS;
|
||||||
|
|
||||||
/* Configure mode */
|
/* Configure mode */
|
||||||
pUart->UART_MR = UART_MR_PAR_NO;
|
pUart->UART_MR = UART_MR_PAR_NO;
|
||||||
|
|
||||||
/* Configure baudrate */
|
/* Configure baudrate */
|
||||||
/* Asynchronous, no oversampling */
|
/* Asynchronous, no oversampling */
|
||||||
pUart->UART_BRGR = (masterClock / baudrate) / 16;
|
//pUart->UART_BRGR = (masterClock / baudrate) / 16;
|
||||||
|
if ((masterClock / baudrate) % 16 >= 7) {
|
||||||
|
pUart->UART_BRGR = ( masterClock / baudrate) / 16 + 1;
|
||||||
|
} else {
|
||||||
|
pUart->UART_BRGR = ( masterClock / baudrate) / 16 + 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Disable PDC channel */
|
/* Disable PDC channel */
|
||||||
pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
|
pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
|
||||||
|
|
||||||
/* Reset transmit ring buffer */
|
/* Reset transmit ring buffer */
|
||||||
rbuf_reset(&uart_tx_buffer);
|
rbuf_reset(&uart_tx_buffer);
|
||||||
|
|
||||||
/* Enable TX interrupts */
|
/* Enable TX interrupts */
|
||||||
pUart->UART_IER = UART_IER_TXRDY;
|
pUart->UART_IER = UART_IER_TXRDY;
|
||||||
NVIC_EnableIRQ(CONSOLE_IRQ);
|
NVIC_EnableIRQ(CONSOLE_IRQ);
|
||||||
|
|
||||||
/* Enable receiver and transmitter */
|
/* Enable receiver and transmitter */
|
||||||
pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
|
pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
|
||||||
|
|
||||||
/* Remember the configuration is complete */
|
/* Remember the configuration is complete */
|
||||||
_ucIsConsoleInitialized=1 ;
|
_ucIsConsoleInitialized=1 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Disables the USART peripheral and related IRQ
|
||||||
|
*/
|
||||||
|
void UART_Exit(void)
|
||||||
|
{
|
||||||
|
if (!_ucIsConsoleInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uart *pUart = CONSOLE_UART;
|
||||||
|
pUart->UART_IDR = UART_IDR_TXRDY;
|
||||||
|
pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS | UART_CR_RSTSTA;
|
||||||
|
PMC->PMC_PCDR0 = 1 << CONSOLE_ID;
|
||||||
|
NVIC_DisableIRQ(CONSOLE_IRQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Interrupt Service routine to transmit queued data */
|
/** Interrupt Service routine to transmit queued data */
|
||||||
@@ -109,7 +131,6 @@ void CONSOLE_ISR(void)
|
|||||||
Uart *uart = CONSOLE_UART;
|
Uart *uart = CONSOLE_UART;
|
||||||
if (uart->UART_SR & UART_SR_TXRDY) {
|
if (uart->UART_SR & UART_SR_TXRDY) {
|
||||||
if (!rbuf_is_empty(&uart_tx_buffer)) {
|
if (!rbuf_is_empty(&uart_tx_buffer)) {
|
||||||
//uart->UART_IER = UART_IER_TXRDY;
|
|
||||||
uart->UART_THR = rbuf_read(&uart_tx_buffer);
|
uart->UART_THR = rbuf_read(&uart_tx_buffer);
|
||||||
} else {
|
} else {
|
||||||
uart->UART_IDR = UART_IER_TXRDY;
|
uart->UART_IDR = UART_IER_TXRDY;
|
||||||
@@ -120,33 +141,48 @@ void CONSOLE_ISR(void)
|
|||||||
/**
|
/**
|
||||||
* \brief Outputs a character on the UART line.
|
* \brief Outputs a character on the UART line.
|
||||||
*
|
*
|
||||||
* \note This function is synchronous (i.e. uses polling).
|
* \note This function is asynchronous (i.e. uses a buffer and interrupt to complete the transfer).
|
||||||
* \param c Character to send.
|
* \param c Character to send.
|
||||||
*/
|
*/
|
||||||
extern void UART_PutChar( uint8_t c )
|
void UART_PutChar( uint8_t uc )
|
||||||
{
|
{
|
||||||
Uart *pUart = CONSOLE_UART ;
|
Uart *pUart = CONSOLE_UART ;
|
||||||
|
|
||||||
/* Initialize console is not already done */
|
/* Initialize console is not already done */
|
||||||
if ( !_ucIsConsoleInitialized )
|
if ( !_ucIsConsoleInitialized )
|
||||||
{
|
{
|
||||||
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
|
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait until there is space in the buffer */
|
if (!rbuf_is_full(&uart_tx_buffer)) {
|
||||||
while (rbuf_is_full(&uart_tx_buffer)) {
|
rbuf_write(&uart_tx_buffer, uc);
|
||||||
if (pUart->UART_SR & UART_SR_TXEMPTY) {
|
if (!(pUart->UART_IMR & UART_IMR_TXRDY)) {
|
||||||
pUart->UART_IER = UART_IER_TXRDY;
|
pUart->UART_IER = UART_IER_TXRDY;
|
||||||
CONSOLE_ISR();
|
CONSOLE_ISR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Put character into buffer */
|
/**
|
||||||
rbuf_write(&uart_tx_buffer, c);
|
* \brief Outputs a character on the UART line.
|
||||||
if (pUart->UART_SR & UART_SR_TXEMPTY) {
|
*
|
||||||
pUart->UART_IER = UART_IER_TXRDY;
|
* \note This function is synchronous (i.e. uses polling and blocks until the transfer is complete).
|
||||||
CONSOLE_ISR();
|
* \param c Character to send.
|
||||||
}
|
*/
|
||||||
|
void UART_PutChar_Sync( uint8_t uc )
|
||||||
|
{
|
||||||
|
Uart *pUart = CONSOLE_UART ;
|
||||||
|
|
||||||
|
/* Initialize console is not already done */
|
||||||
|
if ( !_ucIsConsoleInitialized )
|
||||||
|
{
|
||||||
|
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!(pUart->UART_SR & UART_SR_TXRDY)); /* Wait for transfer buffer to be empty */
|
||||||
|
pUart->UART_THR = uc; /* Send data to UART peripheral */
|
||||||
|
while (!(pUart->UART_SR & UART_SR_TXRDY)); /* Wait for transfer buffer to transferred to shift register */
|
||||||
|
while (!(pUart->UART_SR & UART_SR_TXEMPTY)); /* Wait for transfer shift register to be empty (i.e. transfer is complete) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,17 +193,17 @@ extern void UART_PutChar( uint8_t c )
|
|||||||
*/
|
*/
|
||||||
extern uint32_t UART_GetChar( void )
|
extern uint32_t UART_GetChar( void )
|
||||||
{
|
{
|
||||||
Uart *pUart = CONSOLE_UART ;
|
Uart *pUart = CONSOLE_UART ;
|
||||||
|
|
||||||
if ( !_ucIsConsoleInitialized )
|
if ( !_ucIsConsoleInitialized )
|
||||||
{
|
{
|
||||||
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
|
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( (pUart->UART_SR & UART_SR_RXRDY) == 0 )
|
while ( (pUart->UART_SR & UART_SR_RXRDY) == 0 )
|
||||||
WDT_Restart(WDT);
|
WDT_Restart(WDT);
|
||||||
|
|
||||||
return pUart->UART_RHR ;
|
return pUart->UART_RHR ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,14 +213,14 @@ extern uint32_t UART_GetChar( void )
|
|||||||
*/
|
*/
|
||||||
extern uint32_t UART_IsRxReady( void )
|
extern uint32_t UART_IsRxReady( void )
|
||||||
{
|
{
|
||||||
Uart *pUart = CONSOLE_UART;
|
Uart *pUart = CONSOLE_UART;
|
||||||
|
|
||||||
if ( !_ucIsConsoleInitialized )
|
if ( !_ucIsConsoleInitialized )
|
||||||
{
|
{
|
||||||
UART_Configure( CONSOLE_BAUDRATE, BOARD_MCK ) ;
|
UART_Configure( CONSOLE_BAUDRATE, BOARD_MCK ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (pUart->UART_SR & UART_SR_RXRDY) > 0 ;
|
return (pUart->UART_SR & UART_SR_RXRDY) > 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -195,14 +231,14 @@ extern uint32_t UART_IsRxReady( void )
|
|||||||
*/
|
*/
|
||||||
extern void UART_DumpFrame( uint8_t* pucFrame, uint32_t dwSize )
|
extern void UART_DumpFrame( uint8_t* pucFrame, uint32_t dwSize )
|
||||||
{
|
{
|
||||||
uint32_t dw ;
|
uint32_t dw ;
|
||||||
|
|
||||||
for ( dw=0 ; dw < dwSize ; dw++ )
|
for ( dw=0 ; dw < dwSize ; dw++ )
|
||||||
{
|
{
|
||||||
printf( "%02X ", pucFrame[dw] ) ;
|
printf( "%02X ", pucFrame[dw] ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf( "\n\r" ) ;
|
printf( "\n\r" ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -214,62 +250,62 @@ extern void UART_DumpFrame( uint8_t* pucFrame, uint32_t dwSize )
|
|||||||
*/
|
*/
|
||||||
extern void UART_DumpMemory( uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress )
|
extern void UART_DumpMemory( uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress )
|
||||||
{
|
{
|
||||||
uint32_t i ;
|
uint32_t i ;
|
||||||
uint32_t j ;
|
uint32_t j ;
|
||||||
uint32_t dwLastLineStart ;
|
uint32_t dwLastLineStart ;
|
||||||
uint8_t* pucTmp ;
|
uint8_t* pucTmp ;
|
||||||
|
|
||||||
for ( i=0 ; i < (dwSize / 16) ; i++ )
|
for ( i=0 ; i < (dwSize / 16) ; i++ )
|
||||||
{
|
{
|
||||||
printf( "0x%08X: ", (unsigned int)(dwAddress + (i*16)) ) ;
|
printf( "0x%08X: ", (unsigned int)(dwAddress + (i*16)) ) ;
|
||||||
pucTmp = (uint8_t*)&pucBuffer[i*16] ;
|
pucTmp = (uint8_t*)&pucBuffer[i*16] ;
|
||||||
|
|
||||||
for ( j=0 ; j < 4 ; j++ )
|
for ( j=0 ; j < 4 ; j++ )
|
||||||
{
|
{
|
||||||
printf( "%02X%02X%02X%02X ", pucTmp[0], pucTmp[1], pucTmp[2], pucTmp[3] ) ;
|
printf( "%02X%02X%02X%02X ", pucTmp[0], pucTmp[1], pucTmp[2], pucTmp[3] ) ;
|
||||||
pucTmp += 4 ;
|
pucTmp += 4 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
pucTmp=(uint8_t*)&pucBuffer[i*16] ;
|
pucTmp=(uint8_t*)&pucBuffer[i*16] ;
|
||||||
|
|
||||||
for ( j=0 ; j < 16 ; j++ )
|
for ( j=0 ; j < 16 ; j++ )
|
||||||
{
|
{
|
||||||
UART_PutChar( *pucTmp++ ) ;
|
UART_PutChar( *pucTmp++ ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf( "\n\r" ) ;
|
printf( "\n\r" ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (dwSize%16) != 0 )
|
if ( (dwSize%16) != 0 )
|
||||||
{
|
{
|
||||||
dwLastLineStart=dwSize - (dwSize%16) ;
|
dwLastLineStart=dwSize - (dwSize%16) ;
|
||||||
|
|
||||||
printf( "0x%08X: ", (unsigned int)(dwAddress + dwLastLineStart) ) ;
|
printf( "0x%08X: ", (unsigned int)(dwAddress + dwLastLineStart) ) ;
|
||||||
for ( j=dwLastLineStart ; j < dwLastLineStart+16 ; j++ )
|
for ( j=dwLastLineStart ; j < dwLastLineStart+16 ; j++ )
|
||||||
{
|
{
|
||||||
if ( (j!=dwLastLineStart) && (j%4 == 0) )
|
if ( (j!=dwLastLineStart) && (j%4 == 0) )
|
||||||
{
|
{
|
||||||
printf( " " ) ;
|
printf( " " ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( j < dwSize )
|
if ( j < dwSize )
|
||||||
{
|
{
|
||||||
printf( "%02X", pucBuffer[j] ) ;
|
printf( "%02X", pucBuffer[j] ) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf(" ") ;
|
printf(" ") ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf( " " ) ;
|
printf( " " ) ;
|
||||||
for ( j=dwLastLineStart ; j < dwSize ; j++ )
|
for ( j=dwLastLineStart ; j < dwSize ; j++ )
|
||||||
{
|
{
|
||||||
UART_PutChar( pucBuffer[j] ) ;
|
UART_PutChar( pucBuffer[j] ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf( "\n\r" ) ;
|
printf( "\n\r" ) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -279,46 +315,46 @@ extern void UART_DumpMemory( uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAdd
|
|||||||
*/
|
*/
|
||||||
extern uint32_t UART_GetInteger( uint32_t* pdwValue )
|
extern uint32_t UART_GetInteger( uint32_t* pdwValue )
|
||||||
{
|
{
|
||||||
uint8_t ucKey ;
|
uint8_t ucKey ;
|
||||||
uint8_t ucNbNb=0 ;
|
uint8_t ucNbNb=0 ;
|
||||||
uint32_t dwValue=0 ;
|
uint32_t dwValue=0 ;
|
||||||
|
|
||||||
while ( 1 )
|
while ( 1 )
|
||||||
{
|
{
|
||||||
ucKey=UART_GetChar() ;
|
ucKey=UART_GetChar() ;
|
||||||
UART_PutChar( ucKey ) ;
|
UART_PutChar( ucKey ) ;
|
||||||
|
|
||||||
if ( ucKey >= '0' && ucKey <= '9' )
|
if ( ucKey >= '0' && ucKey <= '9' )
|
||||||
{
|
{
|
||||||
dwValue = (dwValue * 10) + (ucKey - '0');
|
dwValue = (dwValue * 10) + (ucKey - '0');
|
||||||
ucNbNb++ ;
|
ucNbNb++ ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( ucKey == 0x0D || ucKey == ' ' )
|
if ( ucKey == 0x0D || ucKey == ' ' )
|
||||||
{
|
{
|
||||||
if ( ucNbNb == 0 )
|
if ( ucNbNb == 0 )
|
||||||
{
|
{
|
||||||
printf( "\n\rWrite a number and press ENTER or SPACE!\n\r" ) ;
|
printf( "\n\rWrite a number and press ENTER or SPACE!\n\r" ) ;
|
||||||
return 0 ;
|
return 0 ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf( "\n\r" ) ;
|
printf( "\n\r" ) ;
|
||||||
*pdwValue=dwValue ;
|
*pdwValue=dwValue ;
|
||||||
|
|
||||||
return 1 ;
|
return 1 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf( "\n\r'%c' not a number!\n\r", ucKey ) ;
|
printf( "\n\r'%c' not a number!\n\r", ucKey ) ;
|
||||||
|
|
||||||
return 0 ;
|
return 0 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WDT_Restart(WDT);
|
WDT_Restart(WDT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -330,25 +366,25 @@ extern uint32_t UART_GetInteger( uint32_t* pdwValue )
|
|||||||
*/
|
*/
|
||||||
extern uint32_t UART_GetIntegerMinMax( uint32_t* pdwValue, uint32_t dwMin, uint32_t dwMax )
|
extern uint32_t UART_GetIntegerMinMax( uint32_t* pdwValue, uint32_t dwMin, uint32_t dwMax )
|
||||||
{
|
{
|
||||||
uint32_t dwValue=0 ;
|
uint32_t dwValue=0 ;
|
||||||
|
|
||||||
if ( UART_GetInteger( &dwValue ) == 0 )
|
if ( UART_GetInteger( &dwValue ) == 0 )
|
||||||
{
|
{
|
||||||
return 0 ;
|
return 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( dwValue < dwMin || dwValue > dwMax )
|
if ( dwValue < dwMin || dwValue > dwMax )
|
||||||
{
|
{
|
||||||
printf( "\n\rThe number have to be between %d and %d\n\r", (int)dwMin, (int)dwMax ) ;
|
printf( "\n\rThe number have to be between %d and %d\n\r", (int)dwMin, (int)dwMax ) ;
|
||||||
|
|
||||||
return 0 ;
|
return 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf( "\n\r" ) ;
|
printf( "\n\r" ) ;
|
||||||
|
|
||||||
*pdwValue = dwValue ;
|
*pdwValue = dwValue ;
|
||||||
|
|
||||||
return 1 ;
|
return 1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -358,45 +394,45 @@ extern uint32_t UART_GetIntegerMinMax( uint32_t* pdwValue, uint32_t dwMin, uint3
|
|||||||
*/
|
*/
|
||||||
extern uint32_t UART_GetHexa32( uint32_t* pdwValue )
|
extern uint32_t UART_GetHexa32( uint32_t* pdwValue )
|
||||||
{
|
{
|
||||||
uint8_t ucKey ;
|
uint8_t ucKey ;
|
||||||
uint32_t dw = 0 ;
|
uint32_t dw = 0 ;
|
||||||
uint32_t dwValue = 0 ;
|
uint32_t dwValue = 0 ;
|
||||||
|
|
||||||
for ( dw=0 ; dw < 8 ; dw++ )
|
for ( dw=0 ; dw < 8 ; dw++ )
|
||||||
{
|
{
|
||||||
ucKey = UART_GetChar() ;
|
ucKey = UART_GetChar() ;
|
||||||
UART_PutChar( ucKey ) ;
|
UART_PutChar( ucKey ) ;
|
||||||
|
|
||||||
if ( ucKey >= '0' && ucKey <= '9' )
|
if ( ucKey >= '0' && ucKey <= '9' )
|
||||||
{
|
{
|
||||||
dwValue = (dwValue * 16) + (ucKey - '0') ;
|
dwValue = (dwValue * 16) + (ucKey - '0') ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( ucKey >= 'A' && ucKey <= 'F' )
|
if ( ucKey >= 'A' && ucKey <= 'F' )
|
||||||
{
|
{
|
||||||
dwValue = (dwValue * 16) + (ucKey - 'A' + 10) ;
|
dwValue = (dwValue * 16) + (ucKey - 'A' + 10) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( ucKey >= 'a' && ucKey <= 'f' )
|
if ( ucKey >= 'a' && ucKey <= 'f' )
|
||||||
{
|
{
|
||||||
dwValue = (dwValue * 16) + (ucKey - 'a' + 10) ;
|
dwValue = (dwValue * 16) + (ucKey - 'a' + 10) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf( "\n\rIt is not a hexa character!\n\r" ) ;
|
printf( "\n\rIt is not a hexa character!\n\r" ) ;
|
||||||
|
|
||||||
return 0 ;
|
return 0 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n\r" ) ;
|
printf("\n\r" ) ;
|
||||||
*pdwValue = dwValue ;
|
*pdwValue = dwValue ;
|
||||||
|
|
||||||
return 1 ;
|
return 1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined __ICCARM__ /* IAR Ewarm 5.41+ */
|
#if defined __ICCARM__ /* IAR Ewarm 5.41+ */
|
||||||
@@ -409,9 +445,9 @@ extern uint32_t UART_GetHexa32( uint32_t* pdwValue )
|
|||||||
*/
|
*/
|
||||||
extern WEAK signed int putchar( signed int c )
|
extern WEAK signed int putchar( signed int c )
|
||||||
{
|
{
|
||||||
UART_PutChar( c ) ;
|
UART_PutChar( c ) ;
|
||||||
|
|
||||||
return c ;
|
return c ;
|
||||||
}
|
}
|
||||||
#endif // defined __ICCARM__
|
#endif // defined __ICCARM__
|
||||||
|
|
||||||
|
|||||||
170
firmware/libboard/octsimtest/include/board.h
Normal file
170
firmware/libboard/octsimtest/include/board.h
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
/* octSIMtest with SAM3S board definition
|
||||||
|
*
|
||||||
|
* (C) 2019 by sysmocom -s.f.m.c. GmbH, Author:Joachim Steiger <jsteiger@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include "board_common.h"
|
||||||
|
#include "simtrace_usb.h"
|
||||||
|
|
||||||
|
/* Name of the board */
|
||||||
|
#define BOARD_NAME "OCTSIMTEST"
|
||||||
|
/* Board definition */
|
||||||
|
#define octsimtest
|
||||||
|
|
||||||
|
/** oscillator used as main clock source (in Hz) */
|
||||||
|
#define BOARD_MAINOSC 18432000
|
||||||
|
/** desired main clock frequency (in Hz, based on BOARD_MAINOSC) */
|
||||||
|
#define BOARD_MCK 58982400 // 18.432 * 16 / 5
|
||||||
|
|
||||||
|
/** Pin configuration **/
|
||||||
|
|
||||||
|
/** there is no red LED, but the code needs this second LED, thus we provide an unused pin */
|
||||||
|
#define PIO_LED_RED PIO_PB13
|
||||||
|
/** MCU pin connected to green LED, which is actually amber, and the logic is inverted since it is connected to an NPN transistor (used as open drain) */
|
||||||
|
#define PIO_LED_GREEN PIO_PA4
|
||||||
|
/** red LED pin definition */
|
||||||
|
#define PIN_LED_RED {PIO_LED_RED, PIOB, ID_PIOB, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/** green LED pin definition */
|
||||||
|
#define PIN_LED_GREEN {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/** LEDs pin definition */
|
||||||
|
#define PINS_LEDS PIN_LED_RED, PIN_LED_GREEN
|
||||||
|
/** index for red LED in LEDs pin definition array */
|
||||||
|
#define LED_NUM_RED 0
|
||||||
|
/** index for green LED in LEDs pin definition array */
|
||||||
|
#define LED_NUM_GREEN 1
|
||||||
|
|
||||||
|
/* Button to force bootloader start (shorted to ground when pressed */
|
||||||
|
#define PIN_BOOTLOADER_SW {PIO_PA5, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||||
|
|
||||||
|
//FIXME SIM_PWEN_PIN collides with PA5/bootloader_sw on octsimtest
|
||||||
|
/* Enable powering the card using the second 3.3 V output of the LDO (active high) */
|
||||||
|
#define SIM_PWEN_PIN {PIO_PA12, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Enable powering the SIM card */
|
||||||
|
#define PWR_PINS SIM_PWEN_PIN
|
||||||
|
|
||||||
|
// FIXME PA8 is 32khz xtal on octsimtest
|
||||||
|
/* Card presence pin */
|
||||||
|
#define SW_SIM PIO_PA11
|
||||||
|
/* Pull card presence pin high (shorted to ground in card slot when card is present) */
|
||||||
|
#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
|
||||||
|
|
||||||
|
/** Smart card connection **/
|
||||||
|
//FIXME
|
||||||
|
/* Card RST reset signal input (active low; RST_SIM in schematic) */
|
||||||
|
#define PIN_SIM_RST {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Card I/O data signal input/output (I/O_SIM in schematic) */
|
||||||
|
#define PIN_SIM_IO {PIO_PA6A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Card CLK clock input (CLK_SIM in schematic) */
|
||||||
|
#define PIN_SIM_CLK {PIO_PA2B_SCK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
/* Pin to measure card I/O timing (to start measuring the ETU on I/O activity; connected I/O_SIM in schematic) */
|
||||||
|
#define PIN_SIM_IO_INPUT {PIO_PA1B_TIOB0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
//FIXME PIO_PA4B_TCLK0 PA4 is LED on octsimtest
|
||||||
|
/* Pin used as clock input (to measure the ETU duration; connected to CLK_SIM in schematic) */
|
||||||
|
#define PIN_SIM_CLK_INPUT {PIO_PA14, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
/* Pins used to measure ETU timing (using timer counter) */
|
||||||
|
#define PINS_TC PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
|
||||||
|
|
||||||
|
/** Phone connection **/
|
||||||
|
/* Phone USIM slot 1 VCC pin (VCC_PHONE in schematic) */
|
||||||
|
#define PIN_USIM1_VCC {PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
/* Phone USIM slot 1 RST pin (active low; RST_PHONE in schematic) */
|
||||||
|
#define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_RISE_EDGE | PIO_DEGLITCH }
|
||||||
|
/* Phone I/O data signal input/output (I/O_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_IO {PIO_PA22A_TXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Phone CLK clock input (CLK_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_CLK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Pin used for phone USIM slot 1 communication */
|
||||||
|
#define PINS_USIM1 PIN_PHONE_IO, PIN_PHONE_CLK, PIN_PHONE_CLK_INPUT, PIN_USIM1_VCC, PIN_PHONE_IO_INPUT, PIN_USIM1_nRST
|
||||||
|
/* Phone I/O data signal input/output (unused USART RX input; connected to I/O_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_IO_INPUT {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Pin used as clock input (to measure the ETU duration; connected to CLK_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_CLK_INPUT {PIO_PA29B_TCLK2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
|
||||||
|
/** Default pin configuration **/
|
||||||
|
/* Disconnect VPP, CLK, and RST lines between card and phone using bus switch (high sets bus switch to high-impedance) */
|
||||||
|
#define PIN_SC_SW_DEFAULT {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Disconnect I/O line between card and phone using bus switch (high sets bus switch to high-impedance) */
|
||||||
|
#define PIN_IO_SW_DEFAULT {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Disconnect all lines (VPP, CLK, RST, and I/O) between card and phone */
|
||||||
|
#define PINS_BUS_DEFAULT PIN_SC_SW_DEFAULT, PIN_IO_SW_DEFAULT
|
||||||
|
|
||||||
|
/** Sniffer configuration **/
|
||||||
|
/* Connect VPP, CLK, and RST lines between card and phone using bus switch (low connects signals on bus switch) */
|
||||||
|
#define PIN_SC_SW_SNIFF {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Connect I/O line between card and phone using bus switch (low connects signals on bus switch) */
|
||||||
|
#define PIN_IO_SW_SNIFF {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Connect all lines (VPP, CLK, RST, and I/O) between card and phone */
|
||||||
|
#define PINS_BUS_SNIFF PIN_SC_SW_SNIFF, PIN_IO_SW_SNIFF
|
||||||
|
/* Card RST reset signal input (use as input since the phone will drive it) */
|
||||||
|
#define PIN_SIM_RST_SNIFF {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_IT_EDGE}
|
||||||
|
/* Pins used to sniff phone-card communication */
|
||||||
|
#define PINS_SIM_SNIFF PIN_SIM_IO, PIN_SIM_CLK, PIN_SIM_RST_SNIFF
|
||||||
|
/* Disable power converter 4.5-6V to 3.3V (active high) */
|
||||||
|
#define PIN_SIM_PWEN_SNIFF {SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Enable power switch to forward VCC_PHONE to VCC_SIM (active high) */
|
||||||
|
#define PIN_VCC_FWD_SNIFF {VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Use phone VCC to power card */
|
||||||
|
#define PINS_PWR_SNIFF PIN_SIM_PWEN_SNIFF, PIN_VCC_FWD_SNIFF
|
||||||
|
|
||||||
|
/** CCID configuration */
|
||||||
|
/* Card RST reset signal input (active low; RST_SIM in schematic) */
|
||||||
|
#define PIN_ISO7816_RSTMC {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* ISO7816-communication related pins */
|
||||||
|
#define PINS_ISO7816 PIN_SIM_IO, PIN_SIM_CLK, PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2
|
||||||
|
|
||||||
|
/** External SPI flash interface **/
|
||||||
|
/* SPI MISO pin definition */
|
||||||
|
#define PIN_SPI_MISO {PIO_PA12A_MISO, PIOA, PIOA, PIO_PERIPH_A, PIO_PULLUP}
|
||||||
|
/* SPI MOSI pin definition */
|
||||||
|
#define PIN_SPI_MOSI {PIO_PA13A_MOSI, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* SPI SCK pin definition */
|
||||||
|
#define PIN_SPI_SCK {PIO_PA14A_SPCK, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* SPI pins definition. Contains MISO, MOSI & SCK */
|
||||||
|
#define PINS_SPI PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SCK
|
||||||
|
/* SPI chip select 0 pin definition */
|
||||||
|
#define PIN_SPI_NPCS0 {PIO_PA11A_NPCS0, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* SPI flash write protect pin (active low, pulled low) */
|
||||||
|
#define PIN_SPI_WP {PA15, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
|
||||||
|
/** Pin configuration to control USB pull-up on D+
|
||||||
|
* @details the USB pull-up on D+ is enable by default on the board but can be disabled by setting PA16 high
|
||||||
|
*/
|
||||||
|
#define PIN_USB_PULLUP {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
|
||||||
|
/** USB definitions */
|
||||||
|
/* OpenMoko SIMtrace 2 USB vendor ID */
|
||||||
|
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO
|
||||||
|
/* OpenMoko SIMtrace 2 USB product ID (main application/runtime mode) */
|
||||||
|
#define BOARD_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2
|
||||||
|
/* OpenMoko SIMtrace 2 DFU USB product ID (DFU bootloader/DFU mode) */
|
||||||
|
#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2_DFU
|
||||||
|
/* USB release number (bcdDevice, shown as 0.00) */
|
||||||
|
#define BOARD_USB_RELEASE 0x000
|
||||||
|
/* Indicate SIMtrace is bus power in USB attributes */
|
||||||
|
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP
|
||||||
|
|
||||||
|
/** Supported modes */
|
||||||
|
/* SIMtrace board supports sniffer mode */
|
||||||
|
//#define HAVE_SNIFFER
|
||||||
|
/* SIMtrace board supports CCID mode */
|
||||||
|
//#define HAVE_CCID
|
||||||
|
/* SIMtrace board supports card emulation mode */
|
||||||
|
//#define HAVE_CARDEM
|
||||||
|
/* SIMtrace board supports man-in-the-middle mode */
|
||||||
|
//#define HAVE_MITM
|
||||||
|
/* octsimtest board supports gpio_test mode */
|
||||||
|
#define HAVE_GPIO_TEST
|
||||||
28
firmware/libboard/octsimtest/include/i2c.h
Normal file
28
firmware/libboard/octsimtest/include/i2c.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/* I2C EEPROM memory read and write utilities
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void i2c_pin_init(void);
|
||||||
|
|
||||||
|
bool i2c_write_byte(bool send_start, bool send_stop, uint8_t byte);
|
||||||
|
uint8_t i2c_read_byte(bool nack, bool send_stop);
|
||||||
|
void i2c_stop_cond(void);
|
||||||
|
|
||||||
|
int eeprom_write_byte(uint8_t slave, uint8_t addr, uint8_t byte);
|
||||||
|
int eeprom_read_byte(uint8_t slave, uint8_t addr);
|
||||||
25
firmware/libboard/octsimtest/include/mcp23017.h
Normal file
25
firmware/libboard/octsimtest/include/mcp23017.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/* mcp23017 i2c gpio expander read and write utilities
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MCP23017_ADDRESS 0x20
|
||||||
|
|
||||||
|
int mcp23017_init(uint8_t slave);
|
||||||
|
int mcp23017_test(uint8_t slave);
|
||||||
|
int mcp23017_toggle(uint8_t slave);
|
||||||
|
//int mcp23017_write_byte(uint8_t slave, uint8_t addr, uint8_t byte);
|
||||||
|
//int mcp23017_read_byte(uint8_t slave, uint8_t addr);
|
||||||
1
firmware/libboard/octsimtest/product_string.txt
Normal file
1
firmware/libboard/octsimtest/product_string.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sysmoOCTSIM-Tester
|
||||||
81
firmware/libboard/octsimtest/source/board_octsimtest.c
Normal file
81
firmware/libboard/octsimtest/source/board_octsimtest.c
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/* SIMtrace with SAM3S specific application code
|
||||||
|
*
|
||||||
|
* (C) 2017 by Harald Welte <laforge@gnumonks.org>
|
||||||
|
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#include "board.h"
|
||||||
|
#include "simtrace.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "sim_switch.h"
|
||||||
|
#include <osmocom/core/timer.h>
|
||||||
|
#include "usb_buf.h"
|
||||||
|
#include "i2c.h"
|
||||||
|
#include "mcp23017.h"
|
||||||
|
|
||||||
|
void board_exec_dbg_cmd(int ch)
|
||||||
|
{
|
||||||
|
switch (ch) {
|
||||||
|
case '?':
|
||||||
|
printf("\t?\thelp\n\r");
|
||||||
|
printf("\tR\treset SAM3\n\r");
|
||||||
|
printf("\tm\trun mcp23017 test\n\r");
|
||||||
|
printf("\tR\ttoggle MSB of gpio on mcp23017\n\r");
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
printf("Asking NVIC to reset us\n\r");
|
||||||
|
USBD_Disconnect();
|
||||||
|
NVIC_SystemReset();
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
mcp23017_test(MCP23017_ADDRESS);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
mcp23017_toggle(MCP23017_ADDRESS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown command '%c'\n\r", ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_main_top(void)
|
||||||
|
{
|
||||||
|
#ifndef APPLICATION_dfu
|
||||||
|
usb_buf_init();
|
||||||
|
|
||||||
|
i2c_pin_init();
|
||||||
|
if (!mcp23017_init(MCP23017_ADDRESS))
|
||||||
|
printf("mcp23017 not found!\n\r");
|
||||||
|
/* Initialize checking for card insert/remove events */
|
||||||
|
//card_present_init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_override_enter_dfu(void)
|
||||||
|
{
|
||||||
|
const Pin bl_sw_pin = PIN_BOOTLOADER_SW;
|
||||||
|
|
||||||
|
PIO_Configure(&bl_sw_pin, 1);
|
||||||
|
|
||||||
|
/* Enter DFU bootloader in case the respective button is pressed */
|
||||||
|
if (PIO_Get(&bl_sw_pin) == 0) {
|
||||||
|
/* do not print to early since the console is not initialized yet */
|
||||||
|
//printf("BOOTLOADER switch pressed -> Force DFU\n\r");
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
225
firmware/libboard/octsimtest/source/i2c.c
Normal file
225
firmware/libboard/octsimtest/source/i2c.c
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
/* I2C EEPROM memory read and write utilities
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#include "board.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/* Low-Level I2C Routines */
|
||||||
|
|
||||||
|
static const Pin pin_sda = {PIO_PA30, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_OPENDRAIN };
|
||||||
|
static const Pin pin_sda_in = {PIO_PA30, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT };
|
||||||
|
static const Pin pin_scl = {PIO_PA31, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_OPENDRAIN };
|
||||||
|
|
||||||
|
static void i2c_delay()
|
||||||
|
{
|
||||||
|
volatile int v;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* 100 cycles results in SCL peak length of 44us, so it's about
|
||||||
|
* 440ns per cycle here */
|
||||||
|
for (i = 0; i < 14; i++) {
|
||||||
|
v = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void i2c_pin_init(void)
|
||||||
|
{
|
||||||
|
PIO_Configure(&pin_scl, PIO_LISTSIZE(pin_scl));
|
||||||
|
PIO_Configure(&pin_sda, PIO_LISTSIZE(pin_sda));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_scl(void)
|
||||||
|
{
|
||||||
|
PIO_Set(&pin_scl);
|
||||||
|
i2c_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_sda(void)
|
||||||
|
{
|
||||||
|
PIO_Set(&pin_sda);
|
||||||
|
i2c_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_scl(void)
|
||||||
|
{
|
||||||
|
PIO_Clear(&pin_scl);
|
||||||
|
i2c_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_sda(void)
|
||||||
|
{
|
||||||
|
PIO_Clear(&pin_sda);
|
||||||
|
i2c_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool read_sda(void)
|
||||||
|
{
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
PIO_Configure(&pin_sda_in, PIO_LISTSIZE(pin_sda_in));
|
||||||
|
if (PIO_Get(&pin_sda_in))
|
||||||
|
ret = true;
|
||||||
|
else
|
||||||
|
ret = false;
|
||||||
|
PIO_Configure(&pin_sda, PIO_LISTSIZE(pin_sda));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Core I2C Routines */
|
||||||
|
|
||||||
|
static bool i2c_started = false;
|
||||||
|
|
||||||
|
static void i2c_start_cond(void)
|
||||||
|
{
|
||||||
|
if (i2c_started) {
|
||||||
|
set_sda();
|
||||||
|
set_scl();
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_sda();
|
||||||
|
i2c_delay();
|
||||||
|
clear_scl();
|
||||||
|
i2c_started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void i2c_stop_cond(void)
|
||||||
|
{
|
||||||
|
clear_sda();
|
||||||
|
set_scl();
|
||||||
|
set_sda();
|
||||||
|
i2c_delay();
|
||||||
|
i2c_started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_write_bit(bool bit)
|
||||||
|
{
|
||||||
|
if (bit)
|
||||||
|
set_sda();
|
||||||
|
else
|
||||||
|
clear_sda();
|
||||||
|
i2c_delay(); // ?
|
||||||
|
set_scl();
|
||||||
|
clear_scl();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool i2c_read_bit(void)
|
||||||
|
{
|
||||||
|
bool bit;
|
||||||
|
|
||||||
|
set_sda();
|
||||||
|
set_scl();
|
||||||
|
bit = read_sda();
|
||||||
|
clear_scl();
|
||||||
|
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool i2c_write_byte(bool send_start, bool send_stop, uint8_t byte)
|
||||||
|
{
|
||||||
|
uint8_t bit;
|
||||||
|
bool nack;
|
||||||
|
|
||||||
|
if (send_start)
|
||||||
|
i2c_start_cond();
|
||||||
|
|
||||||
|
for (bit = 0; bit < 8; bit++) {
|
||||||
|
i2c_write_bit((byte & 0x80) != 0);
|
||||||
|
byte <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nack = i2c_read_bit();
|
||||||
|
|
||||||
|
if (send_stop)
|
||||||
|
i2c_stop_cond();
|
||||||
|
|
||||||
|
return nack;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t i2c_read_byte(bool nack, bool send_stop)
|
||||||
|
{
|
||||||
|
uint8_t byte = 0;
|
||||||
|
uint8_t bit;
|
||||||
|
|
||||||
|
for (bit = 0; bit < 8; bit++) {
|
||||||
|
byte = (byte << 1) | i2c_read_bit();
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_write_bit(nack);
|
||||||
|
|
||||||
|
if (send_stop)
|
||||||
|
i2c_stop_cond();
|
||||||
|
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* EEPROM related code */
|
||||||
|
|
||||||
|
int eeprom_write_byte(uint8_t slave, uint8_t addr, uint8_t byte)
|
||||||
|
{
|
||||||
|
bool nack;
|
||||||
|
|
||||||
|
WDT_Restart(WDT);
|
||||||
|
|
||||||
|
/* Write slave address */
|
||||||
|
nack = i2c_write_byte(true, false, slave << 1);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
nack = i2c_write_byte(false, false, addr);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
nack = i2c_write_byte(false, true, byte);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
/* Wait tWR time to ensure EEPROM is writing correctly (tWR = 5 ms for AT24C02) */
|
||||||
|
mdelay(5);
|
||||||
|
|
||||||
|
out_stop:
|
||||||
|
i2c_stop_cond();
|
||||||
|
if (nack)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int eeprom_read_byte(uint8_t slave, uint8_t addr)
|
||||||
|
{
|
||||||
|
bool nack;
|
||||||
|
|
||||||
|
WDT_Restart(WDT);
|
||||||
|
|
||||||
|
/* dummy write cycle */
|
||||||
|
nack = i2c_write_byte(true, false, slave << 1);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
nack = i2c_write_byte(false, false, addr);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
/* Re-start with read */
|
||||||
|
nack = i2c_write_byte(true, false, (slave << 1) | 1);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
|
||||||
|
return i2c_read_byte(true, true);
|
||||||
|
|
||||||
|
out_stop:
|
||||||
|
i2c_stop_cond();
|
||||||
|
if (nack)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
140
firmware/libboard/octsimtest/source/mcp23017.c
Normal file
140
firmware/libboard/octsimtest/source/mcp23017.c
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
#include "board.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "i2c.h"
|
||||||
|
#include "mcp23017.h"
|
||||||
|
|
||||||
|
|
||||||
|
//defines from https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.h under BSD license
|
||||||
|
|
||||||
|
// registers
|
||||||
|
#define MCP23017_IODIRA 0x00
|
||||||
|
#define MCP23017_IPOLA 0x02
|
||||||
|
#define MCP23017_GPINTENA 0x04
|
||||||
|
#define MCP23017_DEFVALA 0x06
|
||||||
|
#define MCP23017_INTCONA 0x08
|
||||||
|
#define MCP23017_IOCONA 0x0A
|
||||||
|
#define MCP23017_GPPUA 0x0C
|
||||||
|
#define MCP23017_INTFA 0x0E
|
||||||
|
#define MCP23017_INTCAPA 0x10
|
||||||
|
#define MCP23017_GPIOA 0x12
|
||||||
|
#define MCP23017_OLATA 0x14
|
||||||
|
|
||||||
|
|
||||||
|
#define MCP23017_IODIRB 0x01
|
||||||
|
#define MCP23017_IPOLB 0x03
|
||||||
|
#define MCP23017_GPINTENB 0x05
|
||||||
|
#define MCP23017_DEFVALB 0x07
|
||||||
|
#define MCP23017_INTCONB 0x09
|
||||||
|
#define MCP23017_IOCONB 0x0B
|
||||||
|
#define MCP23017_GPPUB 0x0D
|
||||||
|
#define MCP23017_INTFB 0x0F
|
||||||
|
#define MCP23017_INTCAPB 0x11
|
||||||
|
#define MCP23017_GPIOB 0x13
|
||||||
|
#define MCP23017_OLATB 0x15
|
||||||
|
|
||||||
|
#define MCP23017_INT_ERR 255
|
||||||
|
|
||||||
|
|
||||||
|
//bool i2c_write_byte(bool send_start, bool send_stop, uint8_t byte)
|
||||||
|
//uint8_t i2c_read_byte(bool nack, bool send_stop)
|
||||||
|
//static void i2c_stop_cond(void)
|
||||||
|
|
||||||
|
int mcp23017_write_byte(uint8_t slave, uint8_t addr, uint8_t byte)
|
||||||
|
{
|
||||||
|
bool nack;
|
||||||
|
|
||||||
|
WDT_Restart(WDT);
|
||||||
|
|
||||||
|
// Write slave address
|
||||||
|
nack = i2c_write_byte(true, false, slave << 1);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
nack = i2c_write_byte(false, false, addr);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
nack = i2c_write_byte(false, true, byte);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
|
||||||
|
out_stop:
|
||||||
|
i2c_stop_cond();
|
||||||
|
if (nack)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mcp23017_read_byte(uint8_t slave, uint8_t addr)
|
||||||
|
{
|
||||||
|
bool nack;
|
||||||
|
|
||||||
|
WDT_Restart(WDT);
|
||||||
|
|
||||||
|
// dummy write cycle
|
||||||
|
nack = i2c_write_byte(true, false, slave << 1);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
nack = i2c_write_byte(false, false, addr);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
// Re-start with read
|
||||||
|
nack = i2c_write_byte(true, false, (slave << 1) | 1);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
|
||||||
|
return i2c_read_byte(true, true);
|
||||||
|
|
||||||
|
out_stop:
|
||||||
|
i2c_stop_cond();
|
||||||
|
if (nack)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mcp23017_init(uint8_t slave)
|
||||||
|
{
|
||||||
|
printf("mcp23017_init\n\r");
|
||||||
|
// all gpio input
|
||||||
|
if (mcp23017_write_byte(slave, MCP23017_IODIRA, 0xff))
|
||||||
|
return false;
|
||||||
|
// msb of portb output, rest input
|
||||||
|
if (mcp23017_write_byte(slave, MCP23017_IODIRB, 0x7f))
|
||||||
|
return false;
|
||||||
|
if (mcp23017_write_byte(slave, MCP23017_IOCONA, 0x20)) //disable SEQOP (autoinc addressing)
|
||||||
|
return false;
|
||||||
|
printf("mcp23017 found\n\r");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mcp23017_test(uint8_t slave)
|
||||||
|
{
|
||||||
|
printf("mcp23017_test\n\r");
|
||||||
|
printf("GPIOA 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_GPIOA));
|
||||||
|
printf("GPIOB 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_GPIOB));
|
||||||
|
printf("IODIRA 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_IODIRA));
|
||||||
|
printf("IODIRB 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_IODIRB));
|
||||||
|
printf("IOCONA 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_IOCONA));
|
||||||
|
printf("IOCONB 0x%x\n\r", mcp23017_read_byte(slave,MCP23017_IOCONB));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mcp23017_toggle(uint8_t slave)
|
||||||
|
{
|
||||||
|
// example writing MSB of gpio
|
||||||
|
static bool foo=false;
|
||||||
|
if (foo)
|
||||||
|
{
|
||||||
|
printf("+\n\r");
|
||||||
|
mcp23017_write_byte(slave, MCP23017_OLATB, 0x80);
|
||||||
|
foo=false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("-\n\r");
|
||||||
|
mcp23017_write_byte(slave, MCP23017_OLATB, 0x00);
|
||||||
|
foo=true;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,12 +1,53 @@
|
|||||||
|
/* OWHW board definition
|
||||||
|
*
|
||||||
|
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* (C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "board_common.h"
|
#include "board_common.h"
|
||||||
|
#include "simtrace_usb.h"
|
||||||
|
|
||||||
/** Name of the board */
|
/** Name of the board */
|
||||||
#define BOARD_NAME "OWHW"
|
#define BOARD_NAME "OWHW"
|
||||||
/** Board definition */
|
/** Board definition */
|
||||||
#define owhw
|
#define owhw
|
||||||
|
|
||||||
|
/** oscillator used as main clock source (in Hz) */
|
||||||
#define BOARD_MAINOSC 18432000
|
#define BOARD_MAINOSC 18432000
|
||||||
|
/** desired main clock frequency (in Hz, based on BOARD_MAINOSC) */
|
||||||
|
#define BOARD_MCK 58982400 // 18.432 * 16 / 5
|
||||||
|
|
||||||
|
/** MCU pin connected to red LED */
|
||||||
|
#define PIO_LED_RED PIO_PA17
|
||||||
|
/** MCU pin connected to green LED */
|
||||||
|
#define PIO_LED_GREEN PIO_PA18
|
||||||
|
/** red LED pin definition */
|
||||||
|
#define PIN_LED_RED {PIO_LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/** green LED pin definition */
|
||||||
|
#define PIN_LED_GREEN {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/** LEDs pin definition */
|
||||||
|
#define PINS_LEDS PIN_LED_RED, PIN_LED_GREEN
|
||||||
|
/** index for red LED in LEDs pin definition array */
|
||||||
|
#define LED_NUM_RED 0
|
||||||
|
/** index for green LED in LEDs pin definition array */
|
||||||
|
#define LED_NUM_GREEN 1
|
||||||
|
|
||||||
|
/* pin connected to the SIMTRACE_BOOTLOADER signal. set high to force DFU bootloader start */
|
||||||
|
#define PIN_BOOTLOADER {PIO_PA31, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
|
||||||
/* USIM 2 interface (USART) */
|
/* USIM 2 interface (USART) */
|
||||||
#define PIN_USIM2_CLK {PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
#define PIN_USIM2_CLK {PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
|||||||
1
firmware/libboard/owhw/product_string.txt
Normal file
1
firmware/libboard/owhw/product_string.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
OWHW
|
||||||
@@ -1,28 +1,55 @@
|
|||||||
/* Card simulator specific functions */
|
/* Card simulator specific functions
|
||||||
/* (C) 2015 by Harald Welte <hwelte@hmw-consulting.de>
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
* it under the terms of the GNU General Public License as published by
|
* (C) 2018-2019, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
||||||
* 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,
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* it under the terms of the GNU General Public License as published by
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* GNU General Public License for more details.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* This program is distributed in the hope that it will be useful,
|
||||||
* along with this program; if not, write to the Free Software
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "usb_buf.h"
|
||||||
|
|
||||||
static const Pin pins_cardsim[] = PINS_CARDSIM;
|
static const Pin pins_cardsim[] = PINS_CARDSIM;
|
||||||
|
|
||||||
|
void board_exec_dbg_cmd(int ch)
|
||||||
|
{
|
||||||
|
switch (ch) {
|
||||||
|
case '?':
|
||||||
|
printf("\t?\thelp\n\r");
|
||||||
|
printf("\tR\treset SAM3\n\r");
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
printf("Asking NVIC to reset us\n\r");
|
||||||
|
USBD_Disconnect();
|
||||||
|
NVIC_SystemReset();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown command '%c'\n\r", ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_main_top(void)
|
||||||
|
{
|
||||||
|
#ifndef APPLICATION_dfu
|
||||||
|
usb_buf_init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void cardsim_set_simpres(uint8_t slot, int present)
|
void cardsim_set_simpres(uint8_t slot, int present)
|
||||||
{
|
{
|
||||||
if (slot > 1)
|
if (slot > 1)
|
||||||
@@ -36,5 +63,18 @@ void cardsim_set_simpres(uint8_t slot, int present)
|
|||||||
|
|
||||||
void cardsim_gpio_init(void)
|
void cardsim_gpio_init(void)
|
||||||
{
|
{
|
||||||
PIO_Configure(&pins_cardsim, ARRAY_SIZE(pins_cardsim));
|
PIO_Configure(pins_cardsim, ARRAY_SIZE(pins_cardsim));
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_override_enter_dfu(void)
|
||||||
|
{
|
||||||
|
const Pin bl_pin = PIN_BOOTLOADER;
|
||||||
|
|
||||||
|
PIO_Configure(&bl_pin, 1);
|
||||||
|
|
||||||
|
if (PIO_Get(&bl_pin) == 0) { // signal low
|
||||||
|
return 0; // do not override enter DFU
|
||||||
|
} else {
|
||||||
|
return 1; // override enter DFU
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,53 @@
|
|||||||
|
/* sysmocom quad-modem sysmoQMOD board definition
|
||||||
|
*
|
||||||
|
* (C) 2016-2017 by Harald Welte <hwelte@hmw-consulting.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "board_common.h"
|
#include "board_common.h"
|
||||||
|
#include "simtrace_usb.h"
|
||||||
#define LED_USIM1 LED_GREEN
|
|
||||||
#define LED_USIM2 LED_RED
|
|
||||||
|
|
||||||
/** Name of the board */
|
/** Name of the board */
|
||||||
#define BOARD_NAME "QMOD"
|
#define BOARD_NAME "QMOD"
|
||||||
/** Board definition */
|
/** Board definition */
|
||||||
#define qmod
|
#define qmod
|
||||||
|
|
||||||
|
/** oscillator used as main clock source (in Hz) */
|
||||||
#define BOARD_MAINOSC 12000000
|
#define BOARD_MAINOSC 12000000
|
||||||
|
/** desired main clock frequency (in Hz, based on BOARD_MAINOSC) */
|
||||||
|
#define BOARD_MCK 58000000 // 18.432 * 29 / 6
|
||||||
|
|
||||||
|
/** MCU pin connected to red LED */
|
||||||
|
#define PIO_LED_RED PIO_PA17
|
||||||
|
/** MCU pin connected to green LED */
|
||||||
|
#define PIO_LED_GREEN PIO_PA18
|
||||||
|
/** red LED pin definition */
|
||||||
|
#define PIN_LED_RED {PIO_LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/** green LED pin definition */
|
||||||
|
#define PIN_LED_GREEN {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/** LEDs pin definition */
|
||||||
|
#define PINS_LEDS PIN_LED_RED, PIN_LED_GREEN
|
||||||
|
/** index for red LED in LEDs pin definition array */
|
||||||
|
#define LED_NUM_RED 0
|
||||||
|
/** index for green LED in LEDs pin definition array */
|
||||||
|
#define LED_NUM_GREEN 1
|
||||||
|
/** the green LED is actually red and used as indication for USIM1 */
|
||||||
|
#define LED_USIM1 LED_GREEN
|
||||||
|
/** the green LED is actually red and used as indication for USIM2 */
|
||||||
|
#define LED_USIM2 LED_RED
|
||||||
|
|
||||||
/* USIM 2 interface (USART) */
|
/* USIM 2 interface (USART) */
|
||||||
#define PIN_USIM2_CLK {PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
#define PIN_USIM2_CLK {PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
/* card presence utilities
|
||||||
|
*
|
||||||
|
* (C) 2016-2017 by Harald Welte <hwelte@hmw-consulting.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int is_card_present(int port);
|
int is_card_present(int port);
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/* I2C EEPROM memory read and write utilities
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void i2c_pin_init(void);
|
void i2c_pin_init(void);
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/* Code to read/track the status of the WWAN LEDs of attached modems
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int wwan_led_active(int wwan);
|
int wwan_led_active(int wwan);
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/* Code to control the PERST lines of attached modems
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int wwan_perst_set(int modem_nr, int active);
|
int wwan_perst_set(int modem_nr, int active);
|
||||||
|
|||||||
1
firmware/libboard/qmod/product_string.txt
Normal file
1
firmware/libboard/qmod/product_string.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sysmoQMOD (Quad Modem)
|
||||||
@@ -1,9 +1,26 @@
|
|||||||
/* Quad-modem speciic application code */
|
/* sysmocom quad-modem sysmoQMOD application code
|
||||||
/* (C) 2016-2016 by Harald Welte <laforge@gnumonks.org> */
|
*
|
||||||
|
* (C) 2016-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* (C) 2018-2019, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "simtrace.h"
|
#include "simtrace.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "led.h"
|
||||||
#include "wwan_led.h"
|
#include "wwan_led.h"
|
||||||
#include "wwan_perst.h"
|
#include "wwan_perst.h"
|
||||||
#include "sim_switch.h"
|
#include "sim_switch.h"
|
||||||
@@ -11,6 +28,7 @@
|
|||||||
#include "card_pres.h"
|
#include "card_pres.h"
|
||||||
#include <osmocom/core/timer.h>
|
#include <osmocom/core/timer.h>
|
||||||
#include "usb_buf.h"
|
#include "usb_buf.h"
|
||||||
|
#include "i2c.h"
|
||||||
|
|
||||||
static const Pin pin_hubpwr_override = PIN_PRTPWR_OVERRIDE;
|
static const Pin pin_hubpwr_override = PIN_PRTPWR_OVERRIDE;
|
||||||
static const Pin pin_hub_rst = {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
|
static const Pin pin_hub_rst = {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
|
||||||
@@ -29,6 +47,7 @@ static int qmod_sam3_is_12(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (ALLOW_PEER_ERASE > 0)
|
||||||
const unsigned char __eeprom_bin[256] = {
|
const unsigned char __eeprom_bin[256] = {
|
||||||
USB_VENDOR_OPENMOKO & 0xff,
|
USB_VENDOR_OPENMOKO & 0xff,
|
||||||
USB_VENDOR_OPENMOKO >> 8,
|
USB_VENDOR_OPENMOKO >> 8,
|
||||||
@@ -52,11 +71,8 @@ const unsigned char __eeprom_bin[256] = {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x56, 0x23, 0x71, 0x04, 0x00, /* 0xf0 - 0xff */
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x56, 0x23, 0x71, 0x04, 0x00, /* 0xf0 - 0xff */
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "i2c.h"
|
|
||||||
static int write_hub_eeprom(void)
|
static int write_hub_eeprom(void)
|
||||||
{
|
{
|
||||||
const unsigned int __eeprom_bin_len = 256;
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* wait */
|
/* wait */
|
||||||
@@ -64,22 +80,25 @@ static int write_hub_eeprom(void)
|
|||||||
|
|
||||||
TRACE_INFO("Writing EEPROM...\n\r");
|
TRACE_INFO("Writing EEPROM...\n\r");
|
||||||
/* write the EEPROM once */
|
/* write the EEPROM once */
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < ARRAY_SIZE(__eeprom_bin); i++) {
|
||||||
int rc = eeprom_write_byte(0x50, i, __eeprom_bin[i]);
|
int rc = eeprom_write_byte(0x50, i, __eeprom_bin[i]);
|
||||||
/* if the result was negative, repeat that write */
|
if (rc < 0) {
|
||||||
if (rc < 0)
|
TRACE_ERROR("Writing EEPROM failed at byte %u: 0x%02x\n\r",
|
||||||
i--;
|
i, __eeprom_bin[i]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* then pursue re-reading it again and again */
|
/* then pursue re-reading it again and again */
|
||||||
TRACE_INFO("Verifying EEPROM...\n\r");
|
TRACE_INFO("Verifying EEPROM...\n\r");
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < ARRAY_SIZE(__eeprom_bin); i++) {
|
||||||
int byte = eeprom_read_byte(0x50, i);
|
int byte = eeprom_read_byte(0x50, i);
|
||||||
TRACE_INFO("0x%02x: %02x\n\r", i, byte);
|
TRACE_DEBUG("0x%02x: %02x\n\r", i, byte);
|
||||||
if (byte != __eeprom_bin[i])
|
if (byte != __eeprom_bin[i])
|
||||||
TRACE_ERROR("Byte %u is wrong, expected 0x%02x, found 0x%02x\n\r",
|
TRACE_ERROR("Byte %u is wrong, expected 0x%02x, found 0x%02x\n\r",
|
||||||
i, __eeprom_bin[i], byte);
|
i, __eeprom_bin[i], byte);
|
||||||
}
|
}
|
||||||
|
TRACE_INFO("EEPROM written\n\r");
|
||||||
|
|
||||||
/* FIXME: Release PIN_PRTPWR_OVERRIDE after we know the hub is
|
/* FIXME: Release PIN_PRTPWR_OVERRIDE after we know the hub is
|
||||||
* again powering us up */
|
* again powering us up */
|
||||||
@@ -87,6 +106,29 @@ static int write_hub_eeprom(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int erase_hub_eeprom(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* wait */
|
||||||
|
mdelay(100);
|
||||||
|
|
||||||
|
TRACE_INFO("Erasing EEPROM...\n\r");
|
||||||
|
/* write the EEPROM once */
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
int rc = eeprom_write_byte(0x50, i, 0xff);
|
||||||
|
if (rc < 0) {
|
||||||
|
TRACE_ERROR("Erasing EEPROM failed at byte %u: 0x%02x\n\r",
|
||||||
|
i, __eeprom_bin[i]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE_INFO("EEPROM erased\n\r");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* ALLOW_PEER_ERASE */
|
||||||
|
|
||||||
static void board_exec_dbg_cmd_st12only(int ch)
|
static void board_exec_dbg_cmd_st12only(int ch)
|
||||||
{
|
{
|
||||||
uint32_t addr, val;
|
uint32_t addr, val;
|
||||||
@@ -96,9 +138,14 @@ static void board_exec_dbg_cmd_st12only(int ch)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
#if (ALLOW_PEER_ERASE > 0)
|
||||||
case 'E':
|
case 'E':
|
||||||
write_hub_eeprom();
|
write_hub_eeprom();
|
||||||
break;
|
break;
|
||||||
|
case 'e':
|
||||||
|
erase_hub_eeprom();
|
||||||
|
break;
|
||||||
|
#endif /* ALLOW_PEER_ERASE */
|
||||||
case 'O':
|
case 'O':
|
||||||
printf("Setting PRTPWR_OVERRIDE\n\r");
|
printf("Setting PRTPWR_OVERRIDE\n\r");
|
||||||
PIO_Set(&pin_hubpwr_override);
|
PIO_Set(&pin_hubpwr_override);
|
||||||
@@ -107,6 +154,7 @@ static void board_exec_dbg_cmd_st12only(int ch)
|
|||||||
printf("Clearing PRTPWR_OVERRIDE\n\r");
|
printf("Clearing PRTPWR_OVERRIDE\n\r");
|
||||||
PIO_Clear(&pin_hubpwr_override);
|
PIO_Clear(&pin_hubpwr_override);
|
||||||
break;
|
break;
|
||||||
|
#if (ALLOW_PEER_ERASE > 0)
|
||||||
case 'H':
|
case 'H':
|
||||||
printf("Clearing _HUB_RESET -> HUB_RESET high (inactive)\n\r");
|
printf("Clearing _HUB_RESET -> HUB_RESET high (inactive)\n\r");
|
||||||
PIO_Clear(&pin_hub_rst);
|
PIO_Clear(&pin_hub_rst);
|
||||||
@@ -123,13 +171,14 @@ static void board_exec_dbg_cmd_st12only(int ch)
|
|||||||
UART_GetIntegerMinMax(&addr, 0, 255);
|
UART_GetIntegerMinMax(&addr, 0, 255);
|
||||||
printf("Please enter EEPROM value:\n\r");
|
printf("Please enter EEPROM value:\n\r");
|
||||||
UART_GetIntegerMinMax(&val, 0, 255);
|
UART_GetIntegerMinMax(&val, 0, 255);
|
||||||
printf("Writing value 0x%02x to EEPROM offset 0x%02x\n\r", val, addr);
|
printf("Writing value 0x%02lx to EEPROM offset 0x%02lx\n\r", val, addr);
|
||||||
eeprom_write_byte(0x50, addr, val);
|
eeprom_write_byte(0x50, addr, val);
|
||||||
break;
|
break;
|
||||||
|
#endif /* ALLOW_PEER_ERASE */
|
||||||
case 'r':
|
case 'r':
|
||||||
printf("Please enter EEPROM offset:\n\r");
|
printf("Please enter EEPROM offset:\n\r");
|
||||||
UART_GetIntegerMinMax(&addr, 0, 255);
|
UART_GetIntegerMinMax(&addr, 0, 255);
|
||||||
printf("EEPROM[0x%02x] = 0x%02x\n\r", addr, eeprom_read_byte(0x50, addr));
|
printf("EEPROM[0x%02lx] = 0x%02x\n\r", addr, eeprom_read_byte(0x50, addr));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Unknown command '%c'\n\r", ch);
|
printf("Unknown command '%c'\n\r", ch);
|
||||||
@@ -140,32 +189,70 @@ static void board_exec_dbg_cmd_st12only(int ch)
|
|||||||
/* returns '1' in case we should break any endless loop */
|
/* returns '1' in case we should break any endless loop */
|
||||||
void board_exec_dbg_cmd(int ch)
|
void board_exec_dbg_cmd(int ch)
|
||||||
{
|
{
|
||||||
|
#if (ALLOW_PEER_ERASE > 0)
|
||||||
|
/* this variable controls if it is allowed to assert/release the ERASE line.
|
||||||
|
this is done to prevent accidental ERASE on noisy serial input since only one character can trigger the ERASE.
|
||||||
|
*/
|
||||||
|
static bool allow_erase = false;
|
||||||
|
#endif /* ALLOW_PEER_ERASE */
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '?':
|
case '?':
|
||||||
printf("\t?\thelp\n\r");
|
printf("\t?\thelp\n\r");
|
||||||
printf("\tR\treset SAM3\n\r");
|
printf("\tR\treset SAM3\n\r");
|
||||||
|
printf("\tl\tswitch off LED 1\n\r");
|
||||||
|
printf("\tL\tswitch off LED 1\n\r");
|
||||||
|
printf("\tg\tswitch off LED 2\n\r");
|
||||||
|
printf("\tG\tswitch off LED 2\n\r");
|
||||||
if (qmod_sam3_is_12()) {
|
if (qmod_sam3_is_12()) {
|
||||||
|
#if (ALLOW_PEER_ERASE > 0)
|
||||||
printf("\tE\tprogram EEPROM\n\r");
|
printf("\tE\tprogram EEPROM\n\r");
|
||||||
|
printf("\te\tErase EEPROM\n\r");
|
||||||
|
#endif /* ALLOW_PEER_ERASE */
|
||||||
printf("\tO\tEnable PRTPWR_OVERRIDE\n\r");
|
printf("\tO\tEnable PRTPWR_OVERRIDE\n\r");
|
||||||
printf("\to\tDisable PRTPWR_OVERRIDE\n\r");
|
printf("\to\tDisable PRTPWR_OVERRIDE\n\r");
|
||||||
|
#if (ALLOW_PEER_ERASE > 0)
|
||||||
printf("\tH\tRelease HUB RESET (high)\n\r");
|
printf("\tH\tRelease HUB RESET (high)\n\r");
|
||||||
printf("\th\tAssert HUB RESET (low)\n\r");
|
printf("\th\tAssert HUB RESET (low)\n\r");
|
||||||
printf("\tw\tWrite single byte in EEPROM\n\r");
|
printf("\tw\tWrite single byte in EEPROM\n\r");
|
||||||
|
#endif /* ALLOW_PEER_ERASE */
|
||||||
printf("\tr\tRead single byte from EEPROM\n\r");
|
printf("\tr\tRead single byte from EEPROM\n\r");
|
||||||
}
|
}
|
||||||
printf("\tX\tRelease peer SAM3 from reset\n\r");
|
printf("\tX\tRelease peer SAM3 from reset\n\r");
|
||||||
printf("\tx\tAssert peer SAM3 reset\n\r");
|
printf("\tx\tAssert peer SAM3 reset\n\r");
|
||||||
|
#if (ALLOW_PEER_ERASE > 0)
|
||||||
printf("\tY\tRelease peer SAM3 ERASE signal\n\r");
|
printf("\tY\tRelease peer SAM3 ERASE signal\n\r");
|
||||||
|
printf("\ta\tAllow asserting peer SAM3 ERASE signal\n\r");
|
||||||
printf("\ty\tAssert peer SAM3 ERASE signal\n\r");
|
printf("\ty\tAssert peer SAM3 ERASE signal\n\r");
|
||||||
|
#endif /* ALLOW_PEER_ERASE */
|
||||||
printf("\tU\tProceed to USB Initialization\n\r");
|
printf("\tU\tProceed to USB Initialization\n\r");
|
||||||
printf("\t1\tGenerate 1ms reset pulse on WWAN1\n\r");
|
printf("\t1\tGenerate 1ms reset pulse on WWAN1\n\r");
|
||||||
printf("\t2\tGenerate 1ms reset pulse on WWAN2\n\r");
|
printf("\t2\tGenerate 1ms reset pulse on WWAN2\n\r");
|
||||||
|
printf("\t!\tSwitch Channel A from physical -> remote\n\r");
|
||||||
|
printf("\t@\tSwitch Channel B from physical -> remote\n\r");
|
||||||
|
printf("\tt\t(pseudo)talloc report\n\r");
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
printf("Asking NVIC to reset us\n\r");
|
printf("Asking NVIC to reset us\n\r");
|
||||||
USBD_Disconnect();
|
USBD_Disconnect();
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
led_blink(LED_GREEN, BLINK_ALWAYS_OFF);
|
||||||
|
printf("LED 1 switched off\n\r");
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
led_blink(LED_GREEN, BLINK_ALWAYS_ON);
|
||||||
|
printf("LED 1 switched on\n\r");
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
led_blink(LED_RED, BLINK_ALWAYS_OFF);
|
||||||
|
printf("LED 2 switched off\n\r");
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
led_blink(LED_RED, BLINK_ALWAYS_ON);
|
||||||
|
printf("LED 2 switched on\n\r");
|
||||||
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
printf("Clearing _SIMTRACExx_RST -> SIMTRACExx_RST high (inactive)\n\r");
|
printf("Clearing _SIMTRACExx_RST -> SIMTRACExx_RST high (inactive)\n\r");
|
||||||
PIO_Clear(&pin_peer_rst);
|
PIO_Clear(&pin_peer_rst);
|
||||||
@@ -174,14 +261,24 @@ void board_exec_dbg_cmd(int ch)
|
|||||||
printf("Setting _SIMTRACExx_RST -> SIMTRACExx_RST low (active)\n\r");
|
printf("Setting _SIMTRACExx_RST -> SIMTRACExx_RST low (active)\n\r");
|
||||||
PIO_Set(&pin_peer_rst);
|
PIO_Set(&pin_peer_rst);
|
||||||
break;
|
break;
|
||||||
|
#if (ALLOW_PEER_ERASE > 0)
|
||||||
case 'Y':
|
case 'Y':
|
||||||
printf("Clearing SIMTRACExx_ERASE (inactive)\n\r");
|
printf("Clearing SIMTRACExx_ERASE (inactive)\n\r");
|
||||||
PIO_Clear(&pin_peer_erase);
|
PIO_Clear(&pin_peer_erase);
|
||||||
break;
|
break;
|
||||||
case 'y':
|
case 'a':
|
||||||
printf("Seetting SIMTRACExx_ERASE (active)\n\r");
|
printf("Asserting SIMTRACExx_ERASE allowed on next command\n\r");
|
||||||
PIO_Set(&pin_peer_erase);
|
allow_erase = true;
|
||||||
break;
|
break;
|
||||||
|
case 'y':
|
||||||
|
if (allow_erase) {
|
||||||
|
printf("Setting SIMTRACExx_ERASE (active)\n\r");
|
||||||
|
PIO_Set(&pin_peer_erase);
|
||||||
|
} else {
|
||||||
|
printf("Please first allow setting SIMTRACExx_ERASE\n\r");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* ALLOW_PEER_ERASE */
|
||||||
case '1':
|
case '1':
|
||||||
printf("Resetting Modem 1 (of this SAM3)\n\r");
|
printf("Resetting Modem 1 (of this SAM3)\n\r");
|
||||||
wwan_perst_do_reset_pulse(0, 300);
|
wwan_perst_do_reset_pulse(0, 300);
|
||||||
@@ -196,6 +293,9 @@ void board_exec_dbg_cmd(int ch)
|
|||||||
case '@':
|
case '@':
|
||||||
sim_switch_use_physical(0, 0);
|
sim_switch_use_physical(0, 0);
|
||||||
break;
|
break;
|
||||||
|
case 't':
|
||||||
|
talloc_report(NULL, stdout);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (!qmod_sam3_is_12())
|
if (!qmod_sam3_is_12())
|
||||||
printf("Unknown command '%c'\n\r", ch);
|
printf("Unknown command '%c'\n\r", ch);
|
||||||
@@ -203,6 +303,13 @@ void board_exec_dbg_cmd(int ch)
|
|||||||
board_exec_dbg_cmd_st12only(ch);
|
board_exec_dbg_cmd_st12only(ch);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (ALLOW_PEER_ERASE > 0)
|
||||||
|
// set protection back so it can only run for one command
|
||||||
|
if ('a' != ch) {
|
||||||
|
allow_erase = false;
|
||||||
|
}
|
||||||
|
#endif /* ALLOW_PEER_ERASE */
|
||||||
}
|
}
|
||||||
|
|
||||||
void board_main_top(void)
|
void board_main_top(void)
|
||||||
@@ -235,11 +342,13 @@ void board_main_top(void)
|
|||||||
TRACE_INFO("Detected Quad-Modem ST12\n\r");
|
TRACE_INFO("Detected Quad-Modem ST12\n\r");
|
||||||
} else {
|
} else {
|
||||||
TRACE_INFO("Detected Quad-Modem ST34\n\r");
|
TRACE_INFO("Detected Quad-Modem ST34\n\r");
|
||||||
|
#ifndef APPLICATION_dfu
|
||||||
/* make sure we use the second set of USB Strings
|
/* make sure we use the second set of USB Strings
|
||||||
* calling the interfaces "Modem 3" and "Modem 4" rather
|
* calling the interfaces "Modem 3" and "Modem 4" rather
|
||||||
* than 1+2 */
|
* than 1+2 */
|
||||||
usb_strings[7] = usb_strings[9];
|
usb_strings[7] = usb_strings[9];
|
||||||
usb_strings[8] = usb_strings[10];
|
usb_strings[8] = usb_strings[10];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Obtain the circuit board version (currently just prints voltage */
|
/* Obtain the circuit board version (currently just prints voltage */
|
||||||
@@ -261,20 +370,32 @@ static int uart_has_loopback_jumper(void)
|
|||||||
/* Configure UART pins as I/O */
|
/* Configure UART pins as I/O */
|
||||||
PIO_Configure(uart_loopback_pins, PIO_LISTSIZE(uart_loopback_pins));
|
PIO_Configure(uart_loopback_pins, PIO_LISTSIZE(uart_loopback_pins));
|
||||||
|
|
||||||
|
/* Send pattern over UART TX and check if it is received on RX
|
||||||
|
* If the loop doesn't get interrupted, RxD always follows TxD and thus a
|
||||||
|
* loopback jumper has been placed on RxD/TxD, and we will boot
|
||||||
|
* into DFU unconditionally
|
||||||
|
*/
|
||||||
|
int has_loopback_jumper = 1;
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
/* Set TxD high; abort if RxD doesn't go high either */
|
/* Set TxD high; abort if RxD doesn't go high either */
|
||||||
PIO_Set(&uart_loopback_pins[1]);
|
PIO_Set(&uart_loopback_pins[1]);
|
||||||
if (!PIO_Get(&uart_loopback_pins[0]))
|
if (!PIO_Get(&uart_loopback_pins[0])) {
|
||||||
return 0;
|
has_loopback_jumper = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* Set TxD low, abort if RxD doesn't go low either */
|
/* Set TxD low, abort if RxD doesn't go low either */
|
||||||
PIO_Clear(&uart_loopback_pins[1]);
|
PIO_Clear(&uart_loopback_pins[1]);
|
||||||
if (PIO_Get(&uart_loopback_pins[0]))
|
if (PIO_Get(&uart_loopback_pins[0])) {
|
||||||
return 0;
|
has_loopback_jumper = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* if we reached here, RxD always follows TxD and thus a
|
|
||||||
* loopback jumper has been placed on RxD/TxD, and we will boot
|
/* Put pins back to UART mode */
|
||||||
* into DFU unconditionally */
|
const Pin uart_pins[] = {PINS_UART};
|
||||||
return 1;
|
PIO_Configure(uart_pins, PIO_LISTSIZE(uart_pins));
|
||||||
|
|
||||||
|
return has_loopback_jumper;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_override_enter_dfu(void)
|
int board_override_enter_dfu(void)
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
/* card presence utilities
|
||||||
|
*
|
||||||
|
* (C) 2016-2017 by Harald Welte <hwelte@hmw-consulting.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#include <osmocom/core/timer.h>
|
#include <osmocom/core/timer.h>
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/* I2C EEPROM memory read and write utilities
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
@@ -169,6 +185,8 @@ int eeprom_write_byte(uint8_t slave, uint8_t addr, uint8_t byte)
|
|||||||
nack = i2c_write_byte(false, true, byte);
|
nack = i2c_write_byte(false, true, byte);
|
||||||
if (nack)
|
if (nack)
|
||||||
goto out_stop;
|
goto out_stop;
|
||||||
|
/* Wait tWR time to ensure EEPROM is writing correctly (tWR = 5 ms for AT24C02) */
|
||||||
|
mdelay(5);
|
||||||
|
|
||||||
out_stop:
|
out_stop:
|
||||||
i2c_stop_cond();
|
i2c_stop_cond();
|
||||||
|
|||||||
@@ -1,11 +1,24 @@
|
|||||||
/* Code to read/track the status of the WWAN LEDs of attached modems
|
/* Code to read/track the status of the WWAN LEDs of attached modems
|
||||||
*
|
*
|
||||||
* Depending on the board this is running on, it might be possible
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
/* Depending on the board this is running on, it might be possible
|
||||||
* for the controller to read the status of the WWAN LED output lines of
|
* for the controller to read the status of the WWAN LED output lines of
|
||||||
* the cellular modem. If the board supports this, it sets the
|
* the cellular modem. If the board supports this, it sets the
|
||||||
* PIN_WWAN1 and/or PIN_WWAN2 defines in its board.h file.
|
* PIN_WWAN1 and/or PIN_WWAN2 defines in its board.h file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "wwan_led.h"
|
#include "wwan_led.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,24 @@
|
|||||||
/* Code to control the PERST lines of attached modems
|
/* Code to control the PERST lines of attached modems
|
||||||
*
|
*
|
||||||
* Depending on the board this is running on, it might be possible
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
/* Depending on the board this is running on, it might be possible
|
||||||
* for the controller to set the status of the PERST input line of
|
* for the controller to set the status of the PERST input line of
|
||||||
* the cellular modem. If the board supports this, it sets the
|
* the cellular modem. If the board supports this, it sets the
|
||||||
* PIN_PERST1 and/or PIN_PERST2 defines in its board.h file.
|
* PIN_PERST1 and/or PIN_PERST2 defines in its board.h file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "wwan_perst.h"
|
#include "wwan_perst.h"
|
||||||
|
|||||||
163
firmware/libboard/sam3p256/include/board.h
Normal file
163
firmware/libboard/sam3p256/include/board.h
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
/* Olimiex SAM3S-P256 board definition
|
||||||
|
*
|
||||||
|
* (C) 2019 by Harald Welte <hwelte@hmw-consulting.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include "board_common.h"
|
||||||
|
#include "simtrace_usb.h"
|
||||||
|
|
||||||
|
/* Name of the board */
|
||||||
|
#define BOARD_NAME "SAM3S-P256"
|
||||||
|
/* Board definition */
|
||||||
|
#define simtrace
|
||||||
|
|
||||||
|
/** oscillator used as main clock source (in Hz) */
|
||||||
|
#define BOARD_MAINOSC 12000000
|
||||||
|
/** desired main clock frequency (in Hz, based on BOARD_MAINOSC) */
|
||||||
|
#define BOARD_MCK 58000000
|
||||||
|
|
||||||
|
/** MCU pin connected to yellow LED2 */
|
||||||
|
#define PIO_LED_RED PIO_PA17
|
||||||
|
/** MCU pin connected to green LED1 */
|
||||||
|
#define PIO_LED_GREEN PIO_PA18
|
||||||
|
/** red LED pin definition */
|
||||||
|
#define PIN_LED_RED {PIO_LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/** green LED pin definition */
|
||||||
|
#define PIN_LED_GREEN {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/** LEDs pin definition */
|
||||||
|
#define PINS_LEDS PIN_LED_RED, PIN_LED_GREEN
|
||||||
|
/** index for red LED in LEDs pin definition array */
|
||||||
|
#define LED_NUM_RED 0
|
||||||
|
/** index for green LED in LEDs pin definition array */
|
||||||
|
#define LED_NUM_GREEN 1
|
||||||
|
|
||||||
|
/** Pin configuration **/
|
||||||
|
/* Button to force bootloader start (shorted to ground when pressed */
|
||||||
|
#define PIN_BOOTLOADER_SW {PIO_PA20, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
#if 0
|
||||||
|
/* Enable powering the card using the second 3.3 V output of the LDO (active high) */
|
||||||
|
#define SIM_PWEN_PIN {SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Enable powering the SIM card */
|
||||||
|
#define PWR_PINS SIM_PWEN_PIN
|
||||||
|
/* Card presence pin */
|
||||||
|
#define SW_SIM PIO_PA8
|
||||||
|
/* Pull card presence pin high (shorted to ground in card slot when card is present) */
|
||||||
|
#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
|
||||||
|
|
||||||
|
/** Smart card connection **/
|
||||||
|
/* Card RST reset signal input (active low; RST_SIM in schematic) */
|
||||||
|
#define PIN_SIM_RST {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Card I/O data signal input/output (I/O_SIM in schematic) */
|
||||||
|
#define PIN_SIM_IO {PIO_PA6A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Card CLK clock input (CLK_SIM in schematic) */
|
||||||
|
#define PIN_SIM_CLK {PIO_PA2B_SCK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
/* Pin to measure card I/O timing (to start measuring the ETU on I/O activity; connected I/O_SIM in schematic) */
|
||||||
|
#define PIN_SIM_IO_INPUT {PIO_PA1B_TIOB0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
/* Pin used as clock input (to measure the ETU duration; connected to CLK_SIM in schematic) */
|
||||||
|
#define PIN_SIM_CLK_INPUT {PIO_PA4B_TCLK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
/* Pins used to measure ETU timing (using timer counter) */
|
||||||
|
#define PINS_TC PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
|
||||||
|
|
||||||
|
/** Phone connection **/
|
||||||
|
/* Phone USIM slot 1 VCC pin (VCC_PHONE in schematic) */
|
||||||
|
#define PIN_USIM1_VCC {PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
/* Phone USIM slot 1 RST pin (active low; RST_PHONE in schematic) */
|
||||||
|
#define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_RISE_EDGE | PIO_DEGLITCH }
|
||||||
|
/* Phone I/O data signal input/output (I/O_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_IO {PIO_PA22A_TXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Phone CLK clock input (CLK_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_CLK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Pin used for phone USIM slot 1 communication */
|
||||||
|
#define PINS_USIM1 PIN_PHONE_IO, PIN_PHONE_CLK, PIN_PHONE_CLK_INPUT, PIN_USIM1_VCC, PIN_PHONE_IO_INPUT, PIN_USIM1_nRST
|
||||||
|
/* Phone I/O data signal input/output (unused USART RX input; connected to I/O_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_IO_INPUT {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Pin used as clock input (to measure the ETU duration; connected to CLK_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_CLK_INPUT {PIO_PA29B_TCLK2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
|
||||||
|
/** Default pin configuration **/
|
||||||
|
/* Disconnect VPP, CLK, and RST lines between card and phone using bus switch (high sets bus switch to high-impedance) */
|
||||||
|
#define PIN_SC_SW_DEFAULT {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Disconnect I/O line between card and phone using bus switch (high sets bus switch to high-impedance) */
|
||||||
|
#define PIN_IO_SW_DEFAULT {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Disconnect all lines (VPP, CLK, RST, and I/O) between card and phone */
|
||||||
|
#define PINS_BUS_DEFAULT PIN_SC_SW_DEFAULT, PIN_IO_SW_DEFAULT
|
||||||
|
|
||||||
|
/** Sniffer configuration **/
|
||||||
|
/* Connect VPP, CLK, and RST lines between card and phone using bus switch (low connects signals on bus switch) */
|
||||||
|
#define PIN_SC_SW_SNIFF {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Connect I/O line between card and phone using bus switch (low connects signals on bus switch) */
|
||||||
|
#define PIN_IO_SW_SNIFF {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Connect all lines (VPP, CLK, RST, and I/O) between card and phone */
|
||||||
|
#define PINS_BUS_SNIFF PIN_SC_SW_SNIFF, PIN_IO_SW_SNIFF
|
||||||
|
/* Card RST reset signal input (use as input since the phone will drive it) */
|
||||||
|
#define PIN_SIM_RST_SNIFF {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_IT_EDGE}
|
||||||
|
/* Pins used to sniff phone-card communication */
|
||||||
|
#define PINS_SIM_SNIFF PIN_SIM_IO, PIN_SIM_CLK, PIN_SIM_RST_SNIFF
|
||||||
|
/* Disable power converter 4.5-6V to 3.3V (active high) */
|
||||||
|
#define PIN_SIM_PWEN_SNIFF {SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Enable power switch to forward VCC_PHONE to VCC_SIM (active high) */
|
||||||
|
#define PIN_VCC_FWD_SNIFF {VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Use phone VCC to power card */
|
||||||
|
#define PINS_PWR_SNIFF PIN_SIM_PWEN_SNIFF, PIN_VCC_FWD_SNIFF
|
||||||
|
|
||||||
|
/** CCID configuration */
|
||||||
|
/* Card RST reset signal input (active low; RST_SIM in schematic) */
|
||||||
|
#define PIN_ISO7816_RSTMC {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* ISO7816-communication related pins */
|
||||||
|
#define PINS_ISO7816 PIN_SIM_IO, PIN_SIM_CLK, PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2
|
||||||
|
|
||||||
|
/** External SPI flash interface **/
|
||||||
|
/* SPI MISO pin definition */
|
||||||
|
#define PIN_SPI_MISO {PIO_PA12A_MISO, PIOA, PIOA, PIO_PERIPH_A, PIO_PULLUP}
|
||||||
|
/* SPI MOSI pin definition */
|
||||||
|
#define PIN_SPI_MOSI {PIO_PA13A_MOSI, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* SPI SCK pin definition */
|
||||||
|
#define PIN_SPI_SCK {PIO_PA14A_SPCK, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* SPI pins definition. Contains MISO, MOSI & SCK */
|
||||||
|
#define PINS_SPI PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SCK
|
||||||
|
/* SPI chip select 0 pin definition */
|
||||||
|
#define PIN_SPI_NPCS0 {PIO_PA11A_NPCS0, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* SPI flash write protect pin (active low, pulled low) */
|
||||||
|
#define PIN_SPI_WP {PA15, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Pin configuration to control USB pull-up on D+
|
||||||
|
* @details the USB pull-up on D+ is enable by default on the board but can be disabled by setting PA16 high
|
||||||
|
*/
|
||||||
|
#define PIN_USB_PULLUP {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
|
||||||
|
/** USB definitions */
|
||||||
|
/* OpenMoko SIMtrace 2 USB vendor ID */
|
||||||
|
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO
|
||||||
|
/* OpenMoko SIMtrace 2 USB product ID (main application/runtime mode) */
|
||||||
|
#define BOARD_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2
|
||||||
|
/* OpenMoko SIMtrace 2 DFU USB product ID (DFU bootloader/DFU mode) */
|
||||||
|
#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2_DFU
|
||||||
|
/* USB release number (bcdDevice, shown as 0.00) */
|
||||||
|
#define BOARD_USB_RELEASE 0x000
|
||||||
|
/* Indicate SIMtrace is bus power in USB attributes */
|
||||||
|
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP
|
||||||
|
|
||||||
|
/** Supported modes */
|
||||||
|
/* SIMtrace board supports sniffer mode */
|
||||||
|
#define HAVE_SNIFFER
|
||||||
|
/* SIMtrace board supports CCID mode */
|
||||||
|
//#define HAVE_CCID
|
||||||
|
/* SIMtrace board supports card emulation mode */
|
||||||
|
//#define HAVE_CARDEM
|
||||||
|
/* SIMtrace board supports man-in-the-middle mode */
|
||||||
|
//#define HAVE_MITM
|
||||||
68
firmware/libboard/sam3p256/source/board_sam3p256.c
Normal file
68
firmware/libboard/sam3p256/source/board_sam3p256.c
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/* Olimex SAM3S-P256 specific application code
|
||||||
|
*
|
||||||
|
* (C) 2017,2019 by Harald Welte <laforge@gnumonks.org>
|
||||||
|
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
#include "board.h"
|
||||||
|
#include "simtrace.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "sim_switch.h"
|
||||||
|
#include <osmocom/core/timer.h>
|
||||||
|
#include "usb_buf.h"
|
||||||
|
|
||||||
|
void board_exec_dbg_cmd(int ch)
|
||||||
|
{
|
||||||
|
switch (ch) {
|
||||||
|
case '?':
|
||||||
|
printf("\t?\thelp\n\r");
|
||||||
|
printf("\tR\treset SAM3\n\r");
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
printf("Asking NVIC to reset us\n\r");
|
||||||
|
USBD_Disconnect();
|
||||||
|
NVIC_SystemReset();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown command '%c'\n\r", ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_main_top(void)
|
||||||
|
{
|
||||||
|
#ifndef APPLICATION_dfu
|
||||||
|
usb_buf_init();
|
||||||
|
|
||||||
|
/* Initialize checking for card insert/remove events */
|
||||||
|
//card_present_init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_override_enter_dfu(void)
|
||||||
|
{
|
||||||
|
const Pin bl_sw_pin = PIN_BOOTLOADER_SW;
|
||||||
|
|
||||||
|
PIO_Configure(&bl_sw_pin, 1);
|
||||||
|
|
||||||
|
/* Enter DFU bootloader in case the respective button is pressed */
|
||||||
|
if (PIO_Get(&bl_sw_pin) == 0) {
|
||||||
|
/* do not print to early since the console is not initialized yet */
|
||||||
|
//printf("BOOTLOADER switch pressed -> Force DFU\n\r");
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,88 +1,162 @@
|
|||||||
|
/* SIMtrace with SAM3S board definition
|
||||||
|
*
|
||||||
|
* (C) 2016-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "board_common.h"
|
#include "board_common.h"
|
||||||
|
#include "simtrace_usb.h"
|
||||||
|
|
||||||
/** Name of the board */
|
/* Name of the board */
|
||||||
#define BOARD_NAME "SAM3S-SIMTRACE"
|
#define BOARD_NAME "SAM3S-SIMTRACE"
|
||||||
/** Board definition */
|
/* Board definition */
|
||||||
#define simtrace
|
#define simtrace
|
||||||
|
|
||||||
|
/** oscillator used as main clock source (in Hz) */
|
||||||
#define BOARD_MAINOSC 18432000
|
#define BOARD_MAINOSC 18432000
|
||||||
|
/** desired main clock frequency (in Hz, based on BOARD_MAINOSC) */
|
||||||
|
#define BOARD_MCK 58982400 // 18.432 * 16 / 5
|
||||||
|
|
||||||
/** Phone (SIM card emulator)/CCID Reader/MITM configuration **/
|
/** MCU pin connected to red LED */
|
||||||
/* Normally the communication lines between phone and SIM card are disconnected */
|
#define PIO_LED_RED PIO_PA17
|
||||||
// Disconnect SIM card I/O, VPP line from the phone lines
|
/** MCU pin connected to green LED */
|
||||||
// FIXME: Per default pins are input, therefore high-impedance, therefore they don not activate the bus switch, right?
|
#define PIO_LED_GREEN PIO_PA18
|
||||||
#define PIN_SC_SW_DEFAULT {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
/** red LED pin definition */
|
||||||
// Disconnect SIM card RST, CLK line from the phone lines
|
#define PIN_LED_RED {PIO_LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
#define PIN_IO_SW_DEFAULT {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
/** green LED pin definition */
|
||||||
#define PINS_BUS_DEFAULT PIN_SC_SW_DEFAULT, PIN_IO_SW_DEFAULT
|
#define PIN_LED_GREEN {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/** LEDs pin definition */
|
||||||
|
#define PINS_LEDS PIN_LED_RED, PIN_LED_GREEN
|
||||||
|
/** index for red LED in LEDs pin definition array */
|
||||||
|
#define LED_NUM_RED 0
|
||||||
|
/** index for green LED in LEDs pin definition array */
|
||||||
|
#define LED_NUM_GREEN 1
|
||||||
|
|
||||||
|
/** Pin configuration **/
|
||||||
|
/* Button to force bootloader start (shorted to ground when pressed */
|
||||||
|
#define PIN_BOOTLOADER_SW {PIO_PA31, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||||
|
/* Enable powering the card using the second 3.3 V output of the LDO (active high) */
|
||||||
|
#define SIM_PWEN_PIN {PIO_PA5, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Enable powering the SIM card */
|
||||||
|
#define PWR_PINS SIM_PWEN_PIN
|
||||||
|
/* Card presence pin */
|
||||||
|
#define SW_SIM PIO_PA8
|
||||||
|
/* Pull card presence pin high (shorted to ground in card slot when card is present) */
|
||||||
|
#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
|
||||||
|
|
||||||
|
/** Smart card connection **/
|
||||||
|
/* Card RST reset signal input (active low; RST_SIM in schematic) */
|
||||||
|
#define PIN_SIM_RST {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Card I/O data signal input/output (I/O_SIM in schematic) */
|
||||||
|
#define PIN_SIM_IO {PIO_PA6A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Card CLK clock input (CLK_SIM in schematic) */
|
||||||
|
#define PIN_SIM_CLK {PIO_PA2B_SCK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
/* Pin to measure card I/O timing (to start measuring the ETU on I/O activity; connected I/O_SIM in schematic) */
|
||||||
|
#define PIN_SIM_IO_INPUT {PIO_PA1B_TIOB0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
/* Pin used as clock input (to measure the ETU duration; connected to CLK_SIM in schematic) */
|
||||||
|
#define PIN_SIM_CLK_INPUT {PIO_PA4B_TCLK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
/* Pins used to measure ETU timing (using timer counter) */
|
||||||
|
#define PINS_TC PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
|
||||||
|
|
||||||
|
/** Phone connection **/
|
||||||
|
/* Phone USIM slot 1 VCC pin (VCC_PHONE in schematic) */
|
||||||
|
#define PIN_USIM1_VCC {PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_EDGE | PIO_DEGLITCH }
|
||||||
|
/* Phone USIM slot 1 RST pin (active low; RST_PHONE in schematic) */
|
||||||
|
#define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_EDGE | PIO_DEGLITCH }
|
||||||
|
/* Phone I/O data signal input/output (I/O_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_IO {PIO_PA22A_TXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Phone CLK clock input (CLK_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_CLK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Pin used for phone USIM slot 1 communication */
|
||||||
|
#define PINS_USIM1 PIN_PHONE_IO, PIN_PHONE_CLK, PIN_PHONE_CLK_INPUT, PIN_USIM1_VCC, PIN_PHONE_IO_INPUT, PIN_USIM1_nRST
|
||||||
|
/* Phone I/O data signal input/output (unused USART RX input; connected to I/O_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_IO_INPUT {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* Pin used as clock input (to measure the ETU duration; connected to CLK_PHONE in schematic) */
|
||||||
|
#define PIN_PHONE_CLK_INPUT {PIO_PA29B_TCLK2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
|
||||||
|
/** Default pin configuration **/
|
||||||
|
/* Disconnect VPP, CLK, and RST lines between card and phone using bus switch (high sets bus switch to high-impedance) */
|
||||||
|
#define PIN_SC_SW_DEFAULT {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Disconnect I/O line between card and phone using bus switch (high sets bus switch to high-impedance) */
|
||||||
|
#define PIN_IO_SW_DEFAULT {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Disconnect all lines (VPP, CLK, RST, and I/O) between card and phone */
|
||||||
|
#define PINS_BUS_DEFAULT PIN_SC_SW_DEFAULT, PIN_IO_SW_DEFAULT
|
||||||
|
|
||||||
/** Sniffer configuration **/
|
/** Sniffer configuration **/
|
||||||
// Connect VPP, CLK and RST lines from smartcard to the phone
|
/* Connect VPP, CLK, and RST lines between card and phone using bus switch (low connects signals on bus switch) */
|
||||||
#define PIN_SC_SW_SNIFF {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
#define PIN_SC_SW_SNIFF {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Connect I/O line between card and phone using bus switch (low connects signals on bus switch) */
|
||||||
#define PIN_IO_SW_SNIFF {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
#define PIN_IO_SW_SNIFF {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Connect all lines (VPP, CLK, RST, and I/O) between card and phone */
|
||||||
#define PINS_BUS_SNIFF PIN_SC_SW_SNIFF, PIN_IO_SW_SNIFF
|
#define PINS_BUS_SNIFF PIN_SC_SW_SNIFF, PIN_IO_SW_SNIFF
|
||||||
|
/* Card RST reset signal input (use as input since the phone will drive it) */
|
||||||
|
#define PIN_SIM_RST_SNIFF {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_IT_EDGE}
|
||||||
|
/* Pins used to sniff phone-card communication */
|
||||||
|
#define PINS_SIM_SNIFF PIN_SIM_IO, PIN_SIM_CLK, PIN_SIM_RST_SNIFF
|
||||||
|
/* Disable power converter 4.5-6V to 3.3V (active high) */
|
||||||
|
#define PIN_SIM_PWEN_SNIFF {PIO_PA5, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* Enable power switch to forward VCC_PHONE to VCC_SIM (active high) */
|
||||||
|
#define PIN_VCC_FWD_SNIFF {PIO_PA26, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
/* Use phone VCC to power card */
|
||||||
|
#define PINS_PWR_SNIFF PIN_SIM_PWEN_SNIFF, PIN_VCC_FWD_SNIFF
|
||||||
|
|
||||||
#define PINS_SIM_SNIFF_SIM PIN_PHONE_IO, PIN_PHONE_CLK
|
/** CCID configuration */
|
||||||
|
/* Card RST reset signal input (active low; RST_SIM in schematic) */
|
||||||
|
#define PIN_ISO7816_RSTMC {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
/* ISO7816-communication related pins */
|
||||||
|
#define PINS_ISO7816 PIN_SIM_IO, PIN_SIM_CLK, PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2
|
||||||
|
|
||||||
#define SIM_PWEN_PIN {PIO_PA5, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
/** External SPI flash interface **/
|
||||||
|
/* SPI MISO pin definition */
|
||||||
|
#define PIN_SPI_MISO {PIO_PA12A_MISO, PIOA, PIOA, PIO_PERIPH_A, PIO_PULLUP}
|
||||||
|
/* SPI MOSI pin definition */
|
||||||
|
#define PIN_SPI_MOSI {PIO_PA13A_MOSI, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* SPI SCK pin definition */
|
||||||
|
#define PIN_SPI_SCK {PIO_PA14A_SPCK, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* SPI pins definition. Contains MISO, MOSI & SCK */
|
||||||
|
#define PINS_SPI PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SCK
|
||||||
|
/* SPI chip select 0 pin definition */
|
||||||
|
#define PIN_SPI_NPCS0 {PIO_PA11A_NPCS0, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/* SPI flash write protect pin (active low, pulled low) */
|
||||||
|
#define PIN_SPI_WP {PA15, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
|
||||||
#define PWR_PINS \
|
/** Pin configuration to control USB pull-up on D+
|
||||||
/* Enable power converter 4.5-6V to 3.3V; low: off */ \
|
* @details the USB pull-up on D+ is enable by default on the board but can be disabled by setting PA16 high
|
||||||
{SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}, \
|
*/
|
||||||
/* Enable second power converter: VCC_PHONE to VCC_SIM; high: on */ \
|
#define PIN_USB_PULLUP {PIO_PA16, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
{VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
|
||||||
|
|
||||||
#define SW_SIM PIO_PA8
|
|
||||||
#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
|
|
||||||
//#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_EDGE}
|
|
||||||
|
|
||||||
/// PIN used for resetting the smartcard
|
|
||||||
// FIXME: Card is resetted with pin set to 0 --> PIO_OUTPUT_1 as default is right?
|
|
||||||
#define PIN_ISO7816_RSTMC {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
|
||||||
|
|
||||||
/// Pins used for connect the smartcard
|
|
||||||
#define PIN_SIM_IO_INPUT {PIO_PA1, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
|
||||||
#define PIN_SIM_IO {PIO_PA6, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
|
||||||
#define PIN_SIM_CLK {PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
|
||||||
#define PIN_SIM_CLK_INPUT {PIO_PA4, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
|
||||||
//#define PINS_ISO7816 PIN_USART1_TXD, PIN_USART1_SCK, PIN_ISO7816_RSTMC
|
|
||||||
#define PINS_ISO7816 PIN_SIM_IO, PIN_SIM_CLK, PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2
|
|
||||||
|
|
||||||
#define PINS_TC PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
|
|
||||||
|
|
||||||
#define PIN_USIM1_VCC {PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
|
||||||
#define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_RISE_EDGE | PIO_DEGLITCH }
|
|
||||||
#define PIN_PHONE_IO_INPUT {PIO_PA21, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
|
||||||
#define PIN_PHONE_IO {PIO_PA22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
|
||||||
#define PIN_PHONE_CLK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT} // External Clock Input on PA28
|
|
||||||
//#define PIN_PHONE_CLK {PIO_PA23A_SCK1, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} // External Clock Input on PA28
|
|
||||||
#define PIN_PHONE_CLK_INPUT {PIO_PA29, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
|
||||||
#define PINS_USIM1 PIN_PHONE_IO, PIN_PHONE_CLK, PIN_PHONE_CLK_INPUT, PIN_USIM1_VCC, PIN_PHONE_IO_INPUT, PIN_USIM1_nRST
|
|
||||||
//, VCC_PHONE
|
|
||||||
|
|
||||||
#define PIN_BOOTLOADER_SW {PIO_PA31, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
|
||||||
|
|
||||||
//** SPI interface **/
|
|
||||||
/// SPI MISO pin definition (PA12).
|
|
||||||
#define PIN_SPI_MISO {1 << 12, PIOA, PIOA, PIO_PERIPH_A, PIO_PULLUP}
|
|
||||||
/// SPI MOSI pin definition (PA13).
|
|
||||||
#define PIN_SPI_MOSI {1 << 13, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
|
||||||
/// SPI SPCK pin definition (PA14).
|
|
||||||
#define PIN_SPI_SPCK {1 << 14, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
|
||||||
/// SPI pins definition. Contains MISO, MOSI & SPCK (PA12, PA13 & PA14).
|
|
||||||
#define PINS_SPI PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SPCK
|
|
||||||
/// SPI chip select 0 pin definition (PA11).
|
|
||||||
#define PIN_SPI_NPCS0 {1 << 11, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
|
||||||
|
|
||||||
|
/** USB definitions */
|
||||||
|
/* OpenMoko SIMtrace 2 USB vendor ID */
|
||||||
|
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO
|
||||||
|
/* OpenMoko SIMtrace 2 USB product ID (main application/runtime mode) */
|
||||||
|
#define BOARD_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2
|
||||||
|
/* OpenMoko SIMtrace 2 DFU USB product ID (DFU bootloader/DFU mode) */
|
||||||
|
#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2_DFU
|
||||||
|
/* USB release number (bcdDevice, shown as 0.00) */
|
||||||
|
#define BOARD_USB_RELEASE 0x000
|
||||||
|
/* Indicate SIMtrace is bus power in USB attributes */
|
||||||
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP
|
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP
|
||||||
|
|
||||||
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO
|
/** Supported modes */
|
||||||
#define BOARD_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2
|
/* SIMtrace board supports sniffer mode */
|
||||||
#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2_DFU
|
#define HAVE_SNIFFER
|
||||||
#define BOARD_USB_RELEASE 0x000
|
/* SIMtrace board supports CCID mode */
|
||||||
|
//#define HAVE_CCID
|
||||||
//#define HAVE_SNIFFER
|
/* SIMtrace board supports card emulation mode */
|
||||||
#define HAVE_CCID
|
//#define HAVE_CARDEM
|
||||||
#define HAVE_CARDEM
|
/* SIMtrace board supports man-in-the-middle mode */
|
||||||
//#define HAVE_MITM
|
//#define HAVE_MITM
|
||||||
|
|||||||
1
firmware/libboard/simtrace/product_string.txt
Normal file
1
firmware/libboard/simtrace/product_string.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
SIMtrace 2
|
||||||
@@ -1,6 +1,22 @@
|
|||||||
/* SIMtrace specific application code */
|
/* SIMtrace with SAM3S specific application code
|
||||||
/* (C) 2017 by Harald Welte <laforge@gnumonks.org> */
|
*
|
||||||
|
* (C) 2017 by Harald Welte <laforge@gnumonks.org>
|
||||||
|
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "simtrace.h"
|
#include "simtrace.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@@ -44,7 +60,8 @@ int board_override_enter_dfu(void)
|
|||||||
|
|
||||||
/* Enter DFU bootloader in case the respective button is pressed */
|
/* Enter DFU bootloader in case the respective button is pressed */
|
||||||
if (PIO_Get(&bl_sw_pin) == 0) {
|
if (PIO_Get(&bl_sw_pin) == 0) {
|
||||||
printf("BOOTLOADER switch presssed -> Force DFU\n\r");
|
/* do not print to early since the console is not initialized yet */
|
||||||
|
//printf("BOOTLOADER switch pressed -> Force DFU\n\r");
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -65,41 +65,41 @@
|
|||||||
// Definitions
|
// Definitions
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#if defined(NOASSERT)
|
#if defined(NOASSERT)
|
||||||
#define ASSERT(...)
|
#define ASSERT(...)
|
||||||
#define SANITY_CHECK(...)
|
#define SANITY_CHECK(...)
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if (TRACE_LEVEL == 0)
|
#if (TRACE_LEVEL == 0)
|
||||||
/// Checks that the given condition is true,
|
/// Checks that the given condition is true,
|
||||||
/// otherwise stops the program execution.
|
/// otherwise stops the program execution.
|
||||||
/// \param condition Condition to verify.
|
/// \param condition Condition to verify.
|
||||||
#define ASSERT(condition) { \
|
#define ASSERT(condition) { \
|
||||||
if (!(condition)) { \
|
if (!(condition)) { \
|
||||||
while (1); \
|
while (1); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs the same duty as the ASSERT() macro
|
/// Performs the same duty as the ASSERT() macro
|
||||||
/// \param condition Condition to verify.
|
/// \param condition Condition to verify.
|
||||||
#define SANITY_CHECK(condition) ASSERT(condition, ...)
|
#define SANITY_CHECK(condition) ASSERT(condition, ...)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/// Checks that the given condition is true, otherwise displays an error
|
/// Checks that the given condition is true, otherwise displays an error
|
||||||
/// message and stops the program execution.
|
/// message and stops the program execution.
|
||||||
/// \param condition Condition to verify.
|
/// \param condition Condition to verify.
|
||||||
#define ASSERT(condition) { \
|
#define ASSERT(condition) { \
|
||||||
if (!(condition)) { \
|
if (!(condition)) { \
|
||||||
printf("-F- ASSERT: %s %s:%d\n\r", #condition, __BASE_FILE__, __LINE__); \
|
printf("-F- ASSERT: %s %s:%d\n\r", #condition, __BASE_FILE__, __LINE__); \
|
||||||
while (1); \
|
while (1); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#define SANITY_ERROR "Sanity check failed at %s:%d\n\r"
|
#define SANITY_ERROR "Sanity check failed at %s:%d\n\r"
|
||||||
|
|
||||||
/// Performs the same duty as the ASSERT() macro, except a default error
|
/// Performs the same duty as the ASSERT() macro, except a default error
|
||||||
/// message is output if the condition is false.
|
/// message is output if the condition is false.
|
||||||
/// \param condition Condition to verify.
|
/// \param condition Condition to verify.
|
||||||
#define SANITY_CHECK(condition) ASSERT(condition, SANITY_ERROR, __FILE__, __LINE__)
|
#define SANITY_CHECK(condition) ASSERT(condition, SANITY_ERROR, __FILE__, __LINE__)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/* ISO7816-3 state machine for the card side
|
||||||
|
*
|
||||||
|
* (C) 2010-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -10,8 +29,18 @@ enum card_io {
|
|||||||
CARD_IO_CLK,
|
CARD_IO_CLK,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan,
|
/** initialise card slot
|
||||||
uint8_t in_ep, uint8_t irq_ep);
|
* @param[in] slot_num slot number (arbitrary number)
|
||||||
|
* @param[in] tc_chan timer counter channel (to measure the ETU)
|
||||||
|
* @param[in] uart_chan UART peripheral channel
|
||||||
|
* @param[in] in_ep USB IN end point number
|
||||||
|
* @param[in] irq_ep USB INTerrupt end point number
|
||||||
|
* @param[in] vcc_active initial VCC signal state (true = on)
|
||||||
|
* @param[in] in_reset initial RST signal state (true = reset asserted)
|
||||||
|
* @param[in] clocked initial CLK signat state (true = active)
|
||||||
|
* @return main card handle reference
|
||||||
|
*/
|
||||||
|
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked);
|
||||||
|
|
||||||
/* process a single byte received from the reader */
|
/* process a single byte received from the reader */
|
||||||
void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte);
|
void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte);
|
||||||
@@ -27,7 +56,7 @@ int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len);
|
|||||||
|
|
||||||
struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch);
|
struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch);
|
||||||
void card_emu_have_new_uart_tx(struct card_handle *ch);
|
void card_emu_have_new_uart_tx(struct card_handle *ch);
|
||||||
void card_emu_report_status(struct card_handle *ch);
|
void card_emu_report_status(struct card_handle *ch, bool report_on_irq);
|
||||||
|
|
||||||
#define ENABLE_TX 0x01
|
#define ENABLE_TX 0x01
|
||||||
#define ENABLE_RX 0x02
|
#define ENABLE_RX 0x02
|
||||||
@@ -36,3 +65,8 @@ int card_emu_uart_update_fidi(uint8_t uart_chan, unsigned int fidi);
|
|||||||
int card_emu_uart_tx(uint8_t uart_chan, uint8_t byte);
|
int card_emu_uart_tx(uint8_t uart_chan, uint8_t byte);
|
||||||
void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx);
|
void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx);
|
||||||
void card_emu_uart_wait_tx_idle(uint8_t uart_chan);
|
void card_emu_uart_wait_tx_idle(uint8_t uart_chan);
|
||||||
|
void card_emu_uart_interrupt(uint8_t uart_chan);
|
||||||
|
|
||||||
|
struct cardemu_usb_msg_config;
|
||||||
|
int card_emu_set_config(struct card_handle *ch, const struct cardemu_usb_msg_config *scfg,
|
||||||
|
unsigned int scfg_len);
|
||||||
|
|||||||
@@ -145,129 +145,129 @@ typedef struct
|
|||||||
/// 6.1.11.2 PIN Verification Data Structure
|
/// 6.1.11.2 PIN Verification Data Structure
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/// Number of seconds.
|
/// Number of seconds.
|
||||||
unsigned char bTimerOut;
|
unsigned char bTimerOut;
|
||||||
/// Several parameters for the PIN format options
|
/// Several parameters for the PIN format options
|
||||||
unsigned char bmFormatString;
|
unsigned char bmFormatString;
|
||||||
/// Define the length of the PIN to present in the APDU command
|
/// Define the length of the PIN to present in the APDU command
|
||||||
unsigned char bmPINBlockString;
|
unsigned char bmPINBlockString;
|
||||||
/// Allows the length PIN insertion in the APDU command
|
/// Allows the length PIN insertion in the APDU command
|
||||||
unsigned char bmPINLengthFormat;
|
unsigned char bmPINLengthFormat;
|
||||||
/// Minimum PIN size in digit and Maximum PIN size in digit
|
/// Minimum PIN size in digit and Maximum PIN size in digit
|
||||||
unsigned char wPINMaxExtraDigit;
|
unsigned char wPINMaxExtraDigit;
|
||||||
/// The value is a bit wise OR operation.
|
/// The value is a bit wise OR operation.
|
||||||
unsigned char bEntryValidationCondition;
|
unsigned char bEntryValidationCondition;
|
||||||
/// Number of messages to display for the PIN modify command
|
/// Number of messages to display for the PIN modify command
|
||||||
unsigned char bNumberMessage;
|
unsigned char bNumberMessage;
|
||||||
/// Language used to display the messages.
|
/// Language used to display the messages.
|
||||||
unsigned char wLangId;
|
unsigned char wLangId;
|
||||||
/// Message index in the Reader message table
|
/// Message index in the Reader message table
|
||||||
unsigned char bMsgIndex;
|
unsigned char bMsgIndex;
|
||||||
/// T=1 I-block prologue field to use
|
/// T=1 I-block prologue field to use
|
||||||
unsigned char bTeoPrologue[3];
|
unsigned char bTeoPrologue[3];
|
||||||
/// APDU to send to the ICC
|
/// APDU to send to the ICC
|
||||||
unsigned char abPINApdu[255];
|
unsigned char abPINApdu[255];
|
||||||
}__attribute__ ((packed)) S_ccid_PIN_Verification;
|
}__attribute__ ((packed)) S_ccid_PIN_Verification;
|
||||||
|
|
||||||
|
|
||||||
/// 6.1.11.7 PIN Modification Data Structure
|
/// 6.1.11.7 PIN Modification Data Structure
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/// Number of seconds. If 00h then CCID default value is used.
|
/// Number of seconds. If 00h then CCID default value is used.
|
||||||
unsigned char bTimeOut;
|
unsigned char bTimeOut;
|
||||||
/// Several parameters for the PIN format options (defined in § 6.1.11.4)
|
/// Several parameters for the PIN format options (defined in § 6.1.11.4)
|
||||||
unsigned char bmFormatString4;
|
unsigned char bmFormatString4;
|
||||||
/// Define the length of the PIN to present in the APDU command
|
/// Define the length of the PIN to present in the APDU command
|
||||||
unsigned char bmPINBlockString;
|
unsigned char bmPINBlockString;
|
||||||
/// Allows the length PIN insertion in the APDU command (defined in § 6.1.11.6)
|
/// Allows the length PIN insertion in the APDU command (defined in § 6.1.11.6)
|
||||||
unsigned char bmPinLengthFormat;
|
unsigned char bmPinLengthFormat;
|
||||||
/// Insertion position offset in byte for the current PIN
|
/// Insertion position offset in byte for the current PIN
|
||||||
unsigned char bInsertionOffsetOld;
|
unsigned char bInsertionOffsetOld;
|
||||||
/// Insertion position offset in byte for the new PIN
|
/// Insertion position offset in byte for the new PIN
|
||||||
unsigned char bInsertionOffsetNew;
|
unsigned char bInsertionOffsetNew;
|
||||||
/// XXYYh
|
/// XXYYh
|
||||||
/// XX: Minimum PIN size in digit
|
/// XX: Minimum PIN size in digit
|
||||||
/// YY: Maximum PIN size in digit
|
/// YY: Maximum PIN size in digit
|
||||||
unsigned char wPINMaxExtraDigit;
|
unsigned char wPINMaxExtraDigit;
|
||||||
/// 00h,01h,02h,03h
|
/// 00h,01h,02h,03h
|
||||||
/// Indicates if a confirmation is requested before acceptance of a new PIN (meaning that the user has to enter this new PIN twice before it is accepted)
|
/// Indicates if a confirmation is requested before acceptance of a new PIN (meaning that the user has to enter this new PIN twice before it is accepted)
|
||||||
/// Indicates if the current PIN must be entered and set in the same APDU field of not.
|
/// Indicates if the current PIN must be entered and set in the same APDU field of not.
|
||||||
unsigned char bConfirmPIN;
|
unsigned char bConfirmPIN;
|
||||||
/// The value is a bit wise OR operation.
|
/// The value is a bit wise OR operation.
|
||||||
/// 01h Max size reached
|
/// 01h Max size reached
|
||||||
/// 02h Validation key pressed
|
/// 02h Validation key pressed
|
||||||
/// 04h Timeout occurred
|
/// 04h Timeout occurred
|
||||||
unsigned char bEntryValidationCondition;
|
unsigned char bEntryValidationCondition;
|
||||||
/// 00h,01h,02h,03h,or FFh
|
/// 00h,01h,02h,03h,or FFh
|
||||||
/// Number of messages to display for the PIN modify command.
|
/// Number of messages to display for the PIN modify command.
|
||||||
unsigned char bNumberMessage;
|
unsigned char bNumberMessage;
|
||||||
/// Language used to display the messages. The 16 bit
|
/// Language used to display the messages. The 16 bit
|
||||||
unsigned char wLangId;
|
unsigned char wLangId;
|
||||||
/// Message index in the Reader message table (should be 00h or 01h).
|
/// Message index in the Reader message table (should be 00h or 01h).
|
||||||
unsigned char bMsgIndex1;
|
unsigned char bMsgIndex1;
|
||||||
/// Message index in the Reader message table (should be 01h or 02h).
|
/// Message index in the Reader message table (should be 01h or 02h).
|
||||||
unsigned char bMsgIndex2;
|
unsigned char bMsgIndex2;
|
||||||
/// Message index in the Reader message table (should be 02h).
|
/// Message index in the Reader message table (should be 02h).
|
||||||
unsigned char bMsgIndex3;
|
unsigned char bMsgIndex3;
|
||||||
/// T=1 I-block prologue field to use. Significant only if protocol in use is T=1.
|
/// T=1 I-block prologue field to use. Significant only if protocol in use is T=1.
|
||||||
unsigned char bTeoPrologue[3];
|
unsigned char bTeoPrologue[3];
|
||||||
/// Byte array APDU to send to the ICC
|
/// Byte array APDU to send to the ICC
|
||||||
unsigned char abPINApdu[255];
|
unsigned char abPINApdu[255];
|
||||||
}__attribute__ ((packed)) S_ccid_PIN_Modification;
|
}__attribute__ ((packed)) S_ccid_PIN_Modification;
|
||||||
|
|
||||||
/// Protocol Data Structure for Protocol T=0 (bProtocolNum=0, dwLength=00000005h)
|
/// Protocol Data Structure for Protocol T=0 (bProtocolNum=0, dwLength=00000005h)
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/// B7-4 – FI – Index into the table 7 in ISO/IEC 7816-3:1997 selecting a
|
/// B7-4 – FI – Index into the table 7 in ISO/IEC 7816-3:1997 selecting a
|
||||||
/// clock rate conversion factor
|
/// clock rate conversion factor
|
||||||
/// B3-0 – DI - Index into the table 8 in ISO/IEC 7816-3:1997 selecting a
|
/// B3-0 – DI - Index into the table 8 in ISO/IEC 7816-3:1997 selecting a
|
||||||
/// baud rate conversion factor
|
/// baud rate conversion factor
|
||||||
unsigned char bmFindexDindex;
|
unsigned char bmFindexDindex;
|
||||||
/// For T=0 ,B0 – 0b, B7-2 – 000000b
|
/// For T=0 ,B0 – 0b, B7-2 – 000000b
|
||||||
/// B1 – Convention used (b1=0 for direct, b1=1 for inverse)
|
/// B1 – Convention used (b1=0 for direct, b1=1 for inverse)
|
||||||
unsigned char bmTCCKST0; // 0 to 2
|
unsigned char bmTCCKST0; // 0 to 2
|
||||||
/// Extra Guardtime between two characters. Add 0 to 254 etu to the normal
|
/// Extra Guardtime between two characters. Add 0 to 254 etu to the normal
|
||||||
/// guardtime of 12etu. FFh is the same as 00h.
|
/// guardtime of 12etu. FFh is the same as 00h.
|
||||||
unsigned char bGuardTimeT0; // 0 to FF
|
unsigned char bGuardTimeT0; // 0 to FF
|
||||||
/// WI for T=0 used to define WWT
|
/// WI for T=0 used to define WWT
|
||||||
unsigned char bWaitingIntegerT0; // 0 to FF
|
unsigned char bWaitingIntegerT0; // 0 to FF
|
||||||
/// ICC Clock Stop Support
|
/// ICC Clock Stop Support
|
||||||
/// 00 = Stopping the Clock is not allowed
|
/// 00 = Stopping the Clock is not allowed
|
||||||
/// 01 = Stop with Clock signal Low
|
/// 01 = Stop with Clock signal Low
|
||||||
/// 02 = Stop with Clock signal High
|
/// 02 = Stop with Clock signal High
|
||||||
/// 03 = Stop with Clock either High or Low
|
/// 03 = Stop with Clock either High or Low
|
||||||
unsigned char bClockStop; // 0 to 3
|
unsigned char bClockStop; // 0 to 3
|
||||||
} __attribute__ ((packed)) S_ccid_protocol_t0;
|
} __attribute__ ((packed)) S_ccid_protocol_t0;
|
||||||
|
|
||||||
|
|
||||||
/// Protocol Data Structure for Protocol T=1 (bProtocolNum=1, dwLength=00000007h)
|
/// Protocol Data Structure for Protocol T=1 (bProtocolNum=1, dwLength=00000007h)
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/// B7-4 – FI – Index into the table 7 in ISO/IEC 7816-3:1997 selecting a
|
/// B7-4 – FI – Index into the table 7 in ISO/IEC 7816-3:1997 selecting a
|
||||||
/// clock rate conversion factor
|
/// clock rate conversion factor
|
||||||
/// B3-0 – DI - Index into the table 8 in ISO/IEC 7816-3:1997 selecting a
|
/// B3-0 – DI - Index into the table 8 in ISO/IEC 7816-3:1997 selecting a
|
||||||
/// baud rate conversion factor
|
/// baud rate conversion factor
|
||||||
unsigned char bmFindexDindex;
|
unsigned char bmFindexDindex;
|
||||||
/// For T=1, B7-2 – 000100b
|
/// For T=1, B7-2 – 000100b
|
||||||
/// B0 – Checksum type (b0=0 for LRC, b0=1 for CRC
|
/// B0 – Checksum type (b0=0 for LRC, b0=1 for CRC
|
||||||
/// B1 – Convention used (b1=0 for direct, b1=1 for inverse)
|
/// B1 – Convention used (b1=0 for direct, b1=1 for inverse)
|
||||||
unsigned char bmTCCKST1; // 10h, 11h, 12h, 13h
|
unsigned char bmTCCKST1; // 10h, 11h, 12h, 13h
|
||||||
/// Extra Guardtime (0 to 254 etu between two characters).
|
/// Extra Guardtime (0 to 254 etu between two characters).
|
||||||
/// If value is FFh, then guardtime is reduced by 1.
|
/// If value is FFh, then guardtime is reduced by 1.
|
||||||
unsigned char bGuardTimeT1; // 0 to FF
|
unsigned char bGuardTimeT1; // 0 to FF
|
||||||
/// B7-4 = BWI
|
/// B7-4 = BWI
|
||||||
/// B3-0 = CWI
|
/// B3-0 = CWI
|
||||||
unsigned char bmWaitingIntegersT1; // 0 to 9
|
unsigned char bmWaitingIntegersT1; // 0 to 9
|
||||||
/// ICC Clock Stop Support
|
/// ICC Clock Stop Support
|
||||||
/// 00 = Stopping the Clock is not allowed
|
/// 00 = Stopping the Clock is not allowed
|
||||||
/// 01 = Stop with Clock signal Low
|
/// 01 = Stop with Clock signal Low
|
||||||
/// 02 = Stop with Clock signal High
|
/// 02 = Stop with Clock signal High
|
||||||
/// 03 = Stop with Clock either High or Low
|
/// 03 = Stop with Clock either High or Low
|
||||||
unsigned char bClockStop; // 0 to 3
|
unsigned char bClockStop; // 0 to 3
|
||||||
/// Size of negotiated IFSC
|
/// Size of negotiated IFSC
|
||||||
unsigned char bIFSC; // 0 to FE
|
unsigned char bIFSC; // 0 to FE
|
||||||
/// Nad value used by CCID
|
/// Nad value used by CCID
|
||||||
unsigned char bNadValue; // 0 to FF
|
unsigned char bNadValue; // 0 to FF
|
||||||
} __attribute__ ((packed)) S_ccid_protocol_t1;
|
} __attribute__ ((packed)) S_ccid_protocol_t1;
|
||||||
|
|
||||||
|
|
||||||
@@ -357,8 +357,8 @@ typedef struct
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
extern unsigned char RDRtoPCHardwareError( unsigned char bSlot,
|
extern unsigned char RDRtoPCHardwareError( unsigned char bSlot,
|
||||||
unsigned char bSeq,
|
unsigned char bSeq,
|
||||||
unsigned char bHardwareErrorCode );
|
unsigned char bHardwareErrorCode );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#if !defined(NOAUTOCALLBACK)
|
#if !defined(NOAUTOCALLBACK)
|
||||||
@@ -368,13 +368,13 @@ extern void USBDCallbacks_RequestReceived(const USBGenericRequest *request);
|
|||||||
extern void CCID_SmartCardRequest( void );
|
extern void CCID_SmartCardRequest( void );
|
||||||
extern void CCIDDriver_Initialize( void );
|
extern void CCIDDriver_Initialize( void );
|
||||||
extern unsigned char CCID_Read(void *pBuffer,
|
extern unsigned char CCID_Read(void *pBuffer,
|
||||||
unsigned int dLength,
|
unsigned int dLength,
|
||||||
TransferCallback fCallback,
|
TransferCallback fCallback,
|
||||||
void *pArgument);
|
void *pArgument);
|
||||||
extern unsigned char CCID_Write(void *pBuffer,
|
extern unsigned char CCID_Write(void *pBuffer,
|
||||||
unsigned int dLength,
|
unsigned int dLength,
|
||||||
TransferCallback fCallback,
|
TransferCallback fCallback,
|
||||||
void *pArgument);
|
void *pArgument);
|
||||||
extern unsigned char CCID_Insertion( void );
|
extern unsigned char CCID_Insertion( void );
|
||||||
extern unsigned char CCID_Removal( void );
|
extern unsigned char CCID_Removal( void );
|
||||||
|
|
||||||
|
|||||||
@@ -76,9 +76,9 @@ extern uint32_t ISO7816_GetChar( uint8_t *pCharToReceive, Usart_info *usart);
|
|||||||
|
|
||||||
extern void ISO7816_IccPowerOff(void);
|
extern void ISO7816_IccPowerOff(void);
|
||||||
extern uint32_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
|
extern uint32_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
|
||||||
uint8_t *pMessage,
|
uint8_t *pMessage,
|
||||||
uint16_t wLength,
|
uint16_t wLength,
|
||||||
uint16_t *retlen);
|
uint16_t *retlen);
|
||||||
extern void ISO7816_Escape( void );
|
extern void ISO7816_Escape( void );
|
||||||
extern void ISO7816_RestartClock(void);
|
extern void ISO7816_RestartClock(void);
|
||||||
extern void ISO7816_StopClock( void );
|
extern void ISO7816_StopClock( void );
|
||||||
|
|||||||
@@ -1,6 +1,30 @@
|
|||||||
|
/* ISO7816-3 Fi/Di tables + computation
|
||||||
|
*
|
||||||
|
* (C) 2010-2015 by Harald Welte <laforge@gnumonks.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Table 7 of ISO 7816-3:2006 */
|
||||||
|
extern const uint16_t fi_table[];
|
||||||
|
|
||||||
|
/* Table 8 from ISO 7816-3:2006 */
|
||||||
|
extern const uint8_t di_table[];
|
||||||
|
|
||||||
/* compute the F/D ratio based on Fi and Di values */
|
/* compute the F/D ratio based on Fi and Di values */
|
||||||
int compute_fidi_ratio(uint8_t fi, uint8_t di);
|
int compute_fidi_ratio(uint8_t fi, uint8_t di);
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
/* IRQ-safe linked lists
|
||||||
|
*
|
||||||
|
* (C) 2015-2017 by Harald Welte <laforge@gnumonks.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <osmocom/core/linuxlist.h>
|
#include <osmocom/core/linuxlist.h>
|
||||||
|
|||||||
3
firmware/libcommon/include/main_common.h
Normal file
3
firmware/libcommon/include/main_common.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void print_banner(void);
|
||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/* Ring buffer
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#ifndef SIMTRACE_RINGBUF_H
|
#ifndef SIMTRACE_RINGBUF_H
|
||||||
#define SIMTRACE_RINGBUF_H
|
#define SIMTRACE_RINGBUF_H
|
||||||
|
|
||||||
@@ -5,7 +21,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#define RING_BUFLEN 256
|
#define RING_BUFLEN 1024
|
||||||
|
|
||||||
typedef struct ringbuf {
|
typedef struct ringbuf {
|
||||||
uint8_t buf[RING_BUFLEN];
|
uint8_t buf[RING_BUFLEN];
|
||||||
@@ -16,7 +32,7 @@ typedef struct ringbuf {
|
|||||||
void rbuf_reset(volatile ringbuf * rb);
|
void rbuf_reset(volatile ringbuf * rb);
|
||||||
uint8_t rbuf_read(volatile ringbuf * rb);
|
uint8_t rbuf_read(volatile ringbuf * rb);
|
||||||
uint8_t rbuf_peek(volatile ringbuf * rb);
|
uint8_t rbuf_peek(volatile ringbuf * rb);
|
||||||
void rbuf_write(volatile ringbuf * rb, uint8_t item);
|
int rbuf_write(volatile ringbuf * rb, uint8_t item);
|
||||||
bool rbuf_is_empty(volatile ringbuf * rb);
|
bool rbuf_is_empty(volatile ringbuf * rb);
|
||||||
bool rbuf_is_full(volatile ringbuf * rb);
|
bool rbuf_is_full(volatile ringbuf * rb);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/* SIMtrace 2 mode definitions
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* Copyright (c) 2018-2019, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#ifndef SIMTRACE_H
|
#ifndef SIMTRACE_H
|
||||||
#define SIMTRACE_H
|
#define SIMTRACE_H
|
||||||
|
|
||||||
@@ -5,21 +24,8 @@
|
|||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include <usb/device/dfu/dfu.h>
|
#include <usb/device/dfu/dfu.h>
|
||||||
|
|
||||||
/* Endpoint numbers */
|
|
||||||
#define DATAOUT 1
|
|
||||||
#define DATAIN 2
|
|
||||||
#define INT 3
|
|
||||||
|
|
||||||
#define BUFLEN 512
|
#define BUFLEN 512
|
||||||
|
|
||||||
#define PHONE_DATAOUT 4
|
|
||||||
#define PHONE_DATAIN 5
|
|
||||||
#define PHONE_INT 6
|
|
||||||
|
|
||||||
#define CARDEM_USIM2_DATAOUT DATAOUT
|
|
||||||
#define CARDEM_USIM2_DATAIN DATAIN
|
|
||||||
#define CARDEM_USIM2_INT INT
|
|
||||||
|
|
||||||
#define CLK_MASTER true
|
#define CLK_MASTER true
|
||||||
#define CLK_SLAVE false
|
#define CLK_SLAVE false
|
||||||
|
|
||||||
@@ -52,6 +58,7 @@ enum confNum {
|
|||||||
#ifdef HAVE_MITM
|
#ifdef HAVE_MITM
|
||||||
CFG_NUM_MITM,
|
CFG_NUM_MITM,
|
||||||
#endif
|
#endif
|
||||||
|
CFG_NUM_VERSION,
|
||||||
NUM_CONF
|
NUM_CONF
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,25 +67,28 @@ enum confNum {
|
|||||||
/// device using the CCID driver.
|
/// device using the CCID driver.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/// Configuration descriptor
|
/// Configuration descriptor
|
||||||
USBConfigurationDescriptor configuration;
|
USBConfigurationDescriptor configuration;
|
||||||
/// Interface descriptor
|
/// Interface descriptor
|
||||||
USBInterfaceDescriptor interface;
|
USBInterfaceDescriptor interface;
|
||||||
/// CCID descriptor
|
/// CCID descriptor
|
||||||
CCIDDescriptor ccid;
|
CCIDDescriptor ccid;
|
||||||
/// Bulk OUT endpoint descriptor
|
/// Bulk OUT endpoint descriptor
|
||||||
USBEndpointDescriptor bulkOut;
|
USBEndpointDescriptor bulkOut;
|
||||||
/// Bulk IN endpoint descriptor
|
/// Bulk IN endpoint descriptor
|
||||||
USBEndpointDescriptor bulkIn;
|
USBEndpointDescriptor bulkIn;
|
||||||
/// Interrupt OUT endpoint descriptor
|
/// Interrupt OUT endpoint descriptor
|
||||||
USBEndpointDescriptor interruptIn;
|
USBEndpointDescriptor interruptIn;
|
||||||
DFURT_IF_DESCRIPTOR_STRUCT
|
DFURT_IF_DESCRIPTOR_STRUCT
|
||||||
} __attribute__ ((packed)) CCIDDriverConfigurationDescriptors;
|
} __attribute__ ((packed)) CCIDDriverConfigurationDescriptors;
|
||||||
|
|
||||||
extern const USBConfigurationDescriptor *configurationDescriptorsArr[];
|
extern const USBConfigurationDescriptor *configurationDescriptorsArr[];
|
||||||
|
|
||||||
int check_data_from_phone();
|
/*! Update USART baud rate to Fi/Di ratio
|
||||||
void update_fidi(uint8_t fidi);
|
* @param[io] usart USART peripheral base address
|
||||||
|
* @param[in] fidi FiDi value as provided in TA interface byte
|
||||||
|
*/
|
||||||
|
void update_fidi(Usart_info *usart, uint8_t fidi);
|
||||||
|
|
||||||
void ISR_PhoneRST( const Pin *pPin);
|
void ISR_PhoneRST( const Pin *pPin);
|
||||||
|
|
||||||
@@ -108,6 +118,9 @@ extern void CCID_run( void );
|
|||||||
extern void mode_cardemu_run(void);
|
extern void mode_cardemu_run(void);
|
||||||
extern void MITM_run( void );
|
extern void MITM_run( void );
|
||||||
|
|
||||||
|
/* IRQ functions */
|
||||||
|
extern void Sniffer_usart0_irq(void);
|
||||||
|
extern void Sniffer_usart1_irq(void);
|
||||||
extern void mode_cardemu_usart0_irq(void);
|
extern void mode_cardemu_usart0_irq(void);
|
||||||
extern void mode_cardemu_usart1_irq(void);
|
extern void mode_cardemu_usart1_irq(void);
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
|
/* SIMtrace2 USB protocol
|
||||||
|
*
|
||||||
|
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
/* SIMtrace2 USB protocol */
|
|
||||||
|
|
||||||
/* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.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 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* COMMON HEADER
|
* COMMON HEADER
|
||||||
@@ -30,10 +30,10 @@ enum simtrace_msg_class {
|
|||||||
SIMTRACE_MSGC_GENERIC = 0,
|
SIMTRACE_MSGC_GENERIC = 0,
|
||||||
/* Card Emulation / Forwarding */
|
/* Card Emulation / Forwarding */
|
||||||
SIMTRACE_MSGC_CARDEM,
|
SIMTRACE_MSGC_CARDEM,
|
||||||
/* Modem Control (if modem is attached next to device */
|
/* Modem Control (if modem is attached next to device) */
|
||||||
SIMTRACE_MSGC_MODEM,
|
SIMTRACE_MSGC_MODEM,
|
||||||
/* SIM protocol tracing */
|
/* Reader/phone-car/SIM communication sniff */
|
||||||
SIMTRACE_MSGC_TRACE,
|
SIMTRACE_MSGC_SNIFF,
|
||||||
|
|
||||||
/* first vendor-specific request */
|
/* first vendor-specific request */
|
||||||
_SIMTRACE_MGSC_VENDOR_FIRST = 127,
|
_SIMTRACE_MGSC_VENDOR_FIRST = 127,
|
||||||
@@ -62,6 +62,8 @@ enum simtrace_msg_type_cardem {
|
|||||||
SIMTRACE_MSGT_DO_CEMU_RX_DATA,
|
SIMTRACE_MSGT_DO_CEMU_RX_DATA,
|
||||||
/* Indicate PTS request from phone */
|
/* Indicate PTS request from phone */
|
||||||
SIMTRACE_MSGT_DO_CEMU_PTS,
|
SIMTRACE_MSGT_DO_CEMU_PTS,
|
||||||
|
/* Set configurable parameters */
|
||||||
|
SIMTRACE_MSGT_BD_CEMU_CONFIG,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SIMTRACE_MSGC_MODEM */
|
/* SIMTRACE_MSGC_MODEM */
|
||||||
@@ -74,10 +76,18 @@ enum simtrace_msg_type_modem {
|
|||||||
SIMTRACE_MSGT_BD_MODEM_STATUS,
|
SIMTRACE_MSGT_BD_MODEM_STATUS,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SIMTRACE_MSGC_TRACE */
|
/* SIMTRACE_MSGC_SNIFF */
|
||||||
enum simtrace_msg_type_trace {
|
enum simtrace_msg_type_sniff {
|
||||||
/* FIXME */
|
/* Status change (card inserted, reset, ...) */
|
||||||
_dummy,
|
SIMTRACE_MSGT_SNIFF_CHANGE = 0,
|
||||||
|
/* Fi/Di baudrate change */
|
||||||
|
SIMTRACE_MSGT_SNIFF_FIDI,
|
||||||
|
/* ATR data */
|
||||||
|
SIMTRACE_MSGT_SNIFF_ATR,
|
||||||
|
/* PPS (request or response) data */
|
||||||
|
SIMTRACE_MSGT_SNIFF_PPS,
|
||||||
|
/* TPDU data */
|
||||||
|
SIMTRACE_MSGT_SNIFF_TPDU,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* common message header */
|
/* common message header */
|
||||||
@@ -92,7 +102,7 @@ struct simtrace_msg_hdr {
|
|||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CARD EMULATOR / FORWARDER
|
* Capabilities
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
/* generic capabilities */
|
/* generic capabilities */
|
||||||
@@ -107,7 +117,7 @@ enum simtrace_capability_generic {
|
|||||||
SIMTRACE_CAP_LED_1,
|
SIMTRACE_CAP_LED_1,
|
||||||
/* Has LED2 */
|
/* Has LED2 */
|
||||||
SIMTRACE_CAP_LED_2,
|
SIMTRACE_CAP_LED_2,
|
||||||
/* Has Single-Pole Dual-Throw (local/remote SIM */
|
/* Has Single-Pole Dual-Throw (local/remote SIM) */
|
||||||
SIMTRACE_CAP_SPDT,
|
SIMTRACE_CAP_SPDT,
|
||||||
/* Has Bus-Switch (trace / MITM) */
|
/* Has Bus-Switch (trace / MITM) */
|
||||||
SIMTRACE_CAP_BUS_SWITCH,
|
SIMTRACE_CAP_BUS_SWITCH,
|
||||||
@@ -127,7 +137,7 @@ enum simtrace_capability_generic {
|
|||||||
SIMTRACE_CAP_ASSERT_MODEM_RST,
|
SIMTRACE_CAP_ASSERT_MODEM_RST,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* vendor-specific capabilities of sysmoocm devices */
|
/* vendor-specific capabilities of sysmocom devices */
|
||||||
enum simtrace_capability_vendor {
|
enum simtrace_capability_vendor {
|
||||||
/* Can erase a peer SAM3 controller */
|
/* Can erase a peer SAM3 controller */
|
||||||
SIMTRACE_CAP_SYSMO_QMOD_ERASE_PEER,
|
SIMTRACE_CAP_SYSMO_QMOD_ERASE_PEER,
|
||||||
@@ -137,7 +147,6 @@ enum simtrace_capability_vendor {
|
|||||||
SIMTRACE_CAP_SYSMO_QMOD_RESET_HUB,
|
SIMTRACE_CAP_SYSMO_QMOD_RESET_HUB,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* SIMTRACE_CMD_BD_BOARD_INFO */
|
/* SIMTRACE_CMD_BD_BOARD_INFO */
|
||||||
struct simtrace_board_info {
|
struct simtrace_board_info {
|
||||||
struct {
|
struct {
|
||||||
@@ -247,13 +256,22 @@ struct cardemu_usb_msg_error {
|
|||||||
uint8_t msg[0];
|
uint8_t msg[0];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* enable/disable the generation of DO_STATUS on IRQ endpoint */
|
||||||
|
#define CEMU_FEAT_F_STATUS_IRQ 0x00000001
|
||||||
|
|
||||||
|
/* SIMTRACE_MSGT_BD_CEMU_CONFIG */
|
||||||
|
struct cardemu_usb_msg_config {
|
||||||
|
/* bit-mask of CEMU_FEAT_F flags */
|
||||||
|
uint32_t features;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* MODEM CONTROL
|
* MODEM CONTROL
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
/* SIMTRACE_MSGT_DT_MODEM_RESET */
|
/* SIMTRACE_MSGT_DT_MODEM_RESET */
|
||||||
struct st_modem_reset {
|
struct st_modem_reset {
|
||||||
/* 0: de-assert reset, 1: assert reset, 2: poulse reset */
|
/* 0: de-assert reset, 1: assert reset, 2: pulse reset */
|
||||||
uint8_t asserted;
|
uint8_t asserted;
|
||||||
/* if above is '2', duration of pulse in ms */
|
/* if above is '2', duration of pulse in ms */
|
||||||
uint16_t pulse_duration_msec;
|
uint16_t pulse_duration_msec;
|
||||||
@@ -276,3 +294,40 @@ struct st_modem_status {
|
|||||||
/* bit-field of changed status bits */
|
/* bit-field of changed status bits */
|
||||||
uint8_t changed_mask;
|
uint8_t changed_mask;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* SNIFF
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* SIMTRACE_MSGT_SNIFF_CHANGE flags */
|
||||||
|
#define SNIFF_CHANGE_FLAG_CARD_INSERT (1<<0)
|
||||||
|
#define SNIFF_CHANGE_FLAG_CARD_EJECT (1<<1)
|
||||||
|
#define SNIFF_CHANGE_FLAG_RESET_ASSERT (1<<2)
|
||||||
|
#define SNIFF_CHANGE_FLAG_RESET_DEASSERT (1<<3)
|
||||||
|
#define SNIFF_CHANGE_FLAG_TIMEOUT_WT (1<<4)
|
||||||
|
/* SIMTRACE_MSGT_SNIFF_ATR, SIMTRACE_MSGT_SNIFF_PPS, SIMTRACE_MSGT_SNIFF_TPDU flags */
|
||||||
|
#define SNIFF_DATA_FLAG_ERROR_INCOMPLETE (1<<5)
|
||||||
|
#define SNIFF_DATA_FLAG_ERROR_MALFORMED (1<<6)
|
||||||
|
#define SNIFF_DATA_FLAG_ERROR_CHECKSUM (1<<7)
|
||||||
|
|
||||||
|
/* SIMTRACE_MSGT_SNIFF_CHANGE */
|
||||||
|
struct sniff_change {
|
||||||
|
/* SIMTRACE_MSGT_SNIFF_CHANGE flags */
|
||||||
|
uint32_t flags;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* SIMTRACE_MSGT_SNIFF_FIDI */
|
||||||
|
struct sniff_fidi {
|
||||||
|
/* Fi/Di values as encoded in TA1 */
|
||||||
|
uint8_t fidi;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* SIMTRACE_MSGT_SNIFF_ATR, SIMTRACE_MSGT_SNIFF_PPS, SIMTRACE_MSGT_SNIFF_TPDU */
|
||||||
|
struct sniff_data {
|
||||||
|
/* data flags */
|
||||||
|
uint32_t flags;
|
||||||
|
/* data length */
|
||||||
|
uint16_t length;
|
||||||
|
/* data */
|
||||||
|
uint8_t data[0];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|||||||
67
firmware/libcommon/include/simtrace_usb.h
Normal file
67
firmware/libcommon/include/simtrace_usb.h
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/* SIMtrace 2 USB definitions
|
||||||
|
*
|
||||||
|
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.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 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
/* SIMtrace USB IDs */
|
||||||
|
#define USB_VENDOR_OPENMOKO 0x1d50
|
||||||
|
#define USB_PRODUCT_OWHW_SAM3_DFU 0x4001 /* was 0x4000 */
|
||||||
|
#define USB_PRODUCT_OWHW_SAM3 0x4001
|
||||||
|
#define USB_PRODUCT_QMOD_HUB 0x4002
|
||||||
|
#define USB_PRODUCT_QMOD_SAM3_DFU 0x4004 /* was 0x4003 */
|
||||||
|
#define USB_PRODUCT_QMOD_SAM3 0x4004
|
||||||
|
#define USB_PRODUCT_SIMTRACE2_DFU 0x60e3 /* was 0x60e2 */
|
||||||
|
#define USB_PRODUCT_SIMTRACE2 0x60e3
|
||||||
|
|
||||||
|
/* USB proprietary class */
|
||||||
|
#define USB_CLASS_PROPRIETARY 0xff
|
||||||
|
|
||||||
|
/* SIMtrace USB sub-classes */
|
||||||
|
/*! Sniffer USB sub-class */
|
||||||
|
#define SIMTRACE_SNIFFER_USB_SUBCLASS 1
|
||||||
|
/*! Card-emulation USB sub-class */
|
||||||
|
#define SIMTRACE_CARDEM_USB_SUBCLASS 2
|
||||||
|
|
||||||
|
/* Generic USB endpoint numbers */
|
||||||
|
/*! Card-side USB data out (host to device) endpoint number */
|
||||||
|
#define SIMTRACE_USB_EP_CARD_DATAOUT 1
|
||||||
|
/*! Card-side USB data in (device to host) endpoint number */
|
||||||
|
#define SIMTRACE_USB_EP_CARD_DATAIN 2
|
||||||
|
/*! Card-side USB interrupt endpoint number */
|
||||||
|
#define SIMTRACE_USB_EP_CARD_INT 3
|
||||||
|
/*! Phone-side USB data out (host to device) endpoint number */
|
||||||
|
#define SIMTRACE_USB_EP_PHONE_DATAOUT 4
|
||||||
|
/*! Phone-side USB data in (device to host) endpoint number */
|
||||||
|
#define SIMTRACE_USB_EP_PHONE_DATAIN 5
|
||||||
|
/*! Phone-side USB interrupt endpoint number */
|
||||||
|
#define SIMTRACE_USB_EP_PHONE_INT 6
|
||||||
|
|
||||||
|
/* Card-emulation USB endpoint numbers */
|
||||||
|
/*! USIM1 USB data out (host to device) endpoint number */
|
||||||
|
#define SIMTRACE_CARDEM_USB_EP_USIM1_DATAOUT 4
|
||||||
|
/*! USIM1 USB data in (device to host) endpoint number */
|
||||||
|
#define SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN 5
|
||||||
|
/*! USIM1 USB interrupt endpoint number */
|
||||||
|
#define SIMTRACE_CARDEM_USB_EP_USIM1_INT 6
|
||||||
|
/*! USIM2 USB data out (host to device) endpoint number */
|
||||||
|
#define SIMTRACE_CARDEM_USB_EP_USIM2_DATAOUT 1
|
||||||
|
/*! USIM2 USB data in (device to host) endpoint number */
|
||||||
|
#define SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN 2
|
||||||
|
/*! USIM2 USB interrupt endpoint number */
|
||||||
|
#define SIMTRACE_CARDEM_USB_EP_USIM2_INT 3
|
||||||
|
|
||||||
|
/*! Maximum number of endpoints */
|
||||||
|
#define BOARD_USB_NUMENDPOINTS 7 /* 0 (control) + 2 (interfaces) * 3 (endpoints) */
|
||||||
@@ -1,3 +1,31 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2008, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -24,9 +52,14 @@ signed int printf(const char *pFormat, ...);
|
|||||||
signed int sprintf(char *pStr, const char *pFormat, ...);
|
signed int sprintf(char *pStr, const char *pFormat, ...);
|
||||||
signed int puts(const char *pStr);
|
signed int puts(const char *pStr);
|
||||||
|
|
||||||
|
|
||||||
int fputc(int c, FILE *stream);
|
int fputc(int c, FILE *stream);
|
||||||
int fputs(const char *s, FILE *stream);
|
int fputs(const char *s, FILE *stream);
|
||||||
|
|
||||||
#define putc(c, stream) fputc(c, stream)
|
#define putc(c, stream) fputc(c, stream)
|
||||||
#define putchar(c) fputc(c, stdout)
|
#define putchar(c) fputc(c, stdout)
|
||||||
|
|
||||||
|
signed int vfprintf_sync(FILE *pStream, const char *pFormat, va_list ap);
|
||||||
|
signed int vprintf_sync(const char *pFormat, va_list ap);
|
||||||
|
signed int printf_sync(const char *pFormat, ...);
|
||||||
|
int fputc_sync(int c, FILE *stream);
|
||||||
|
int fputs_sync(const char *s, FILE *stream);
|
||||||
|
|||||||
@@ -1,6 +1,23 @@
|
|||||||
|
/* Memory allocation library
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/* minimalistic emulation of core talloc API functions used by msgb.c */
|
/* minimalistic emulation of core talloc API functions used by msgb.c */
|
||||||
@@ -23,3 +40,4 @@ void *talloc_named_const(const void *context, size_t size, const char *name);
|
|||||||
void talloc_set_name_const(const void *ptr, const char *name);
|
void talloc_set_name_const(const void *ptr, const char *name);
|
||||||
char *talloc_strdup(const void *t, const char *p);
|
char *talloc_strdup(const void *t, const char *p);
|
||||||
void *talloc_pool(const void *context, size_t size);
|
void *talloc_pool(const void *context, size_t size);
|
||||||
|
void talloc_report(const void *ptr, FILE *f);
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/* USB buffer library
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <osmocom/core/linuxlist.h>
|
#include <osmocom/core/linuxlist.h>
|
||||||
@@ -13,6 +29,8 @@ struct usb_buffered_ep {
|
|||||||
volatile uint32_t in_progress;
|
volatile uint32_t in_progress;
|
||||||
/* Tx queue (IN) / Rx queue (OUT) */
|
/* Tx queue (IN) / Rx queue (OUT) */
|
||||||
struct llist_head queue;
|
struct llist_head queue;
|
||||||
|
/* current length of queue */
|
||||||
|
unsigned int queue_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msgb *usb_buf_alloc(uint8_t ep);
|
struct msgb *usb_buf_alloc(uint8_t ep);
|
||||||
@@ -24,5 +42,15 @@ int usb_drain_queue(uint8_t ep);
|
|||||||
void usb_buf_init(void);
|
void usb_buf_init(void);
|
||||||
struct usb_buffered_ep *usb_get_buf_ep(uint8_t ep);
|
struct usb_buffered_ep *usb_get_buf_ep(uint8_t ep);
|
||||||
|
|
||||||
int usb_refill_to_host(uint8_t ep);
|
struct usb_if {
|
||||||
int usb_refill_from_host(uint8_t ep);
|
uint8_t if_num; /* interface number */
|
||||||
|
uint8_t ep_out; /* OUT endpoint (0 if none) */
|
||||||
|
uint8_t ep_in; /* IN endpint (0 if none) */
|
||||||
|
uint8_t ep_int; /* INT endpoint (0 if none) */
|
||||||
|
void *data; /* opaque data, passed through */
|
||||||
|
struct {
|
||||||
|
/* call-back to be called for inclming messages on OUT EP */
|
||||||
|
void (*rx_out)(struct msgb *msg, const struct usb_if *usb_if);
|
||||||
|
} ops;
|
||||||
|
};
|
||||||
|
void usb_process(const struct usb_if *usb_if);
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/* General utilities
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|||||||
@@ -1,24 +1,22 @@
|
|||||||
/* ISO7816-3 state machine for the card side */
|
/* ISO7816-3 state machine for the card side
|
||||||
/* (C) 2010-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* (C) 2010-2019 by Harald Welte <laforge@gnumonks.org>
|
||||||
* it under the terms of the GNU General Public License as published by
|
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
||||||
* 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,
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* it under the terms of the GNU General Public License as published by
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* GNU General Public License for more details.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* This program is distributed in the hope that it will be useful,
|
||||||
* along with this program; if not, write to the Free Software
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define TRACE_LEVEL 6
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -39,6 +37,9 @@
|
|||||||
|
|
||||||
#define NUM_SLOTS 2
|
#define NUM_SLOTS 2
|
||||||
|
|
||||||
|
/* bit-mask of supported CEMU_FEAT_F_ flags */
|
||||||
|
#define SUPPORTED_FEATURES (CEMU_FEAT_F_STATUS_IRQ)
|
||||||
|
|
||||||
#define ISO7816_3_INIT_WTIME 9600
|
#define ISO7816_3_INIT_WTIME 9600
|
||||||
#define ISO7816_3_DEFAULT_WI 10
|
#define ISO7816_3_DEFAULT_WI 10
|
||||||
#define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */
|
#define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */
|
||||||
@@ -56,6 +57,19 @@ enum iso7816_3_card_state {
|
|||||||
ISO_S_IN_TPDU, /* inside a TPDU */
|
ISO_S_IN_TPDU, /* inside a TPDU */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct value_string iso7816_3_card_state_names[] = {
|
||||||
|
{ ISO_S_WAIT_POWER, "WAIT_POWER" },
|
||||||
|
{ ISO_S_WAIT_CLK, "WAIT_CLK" },
|
||||||
|
{ ISO_S_WAIT_RST, "WAIT_RST" },
|
||||||
|
{ ISO_S_WAIT_ATR, "WAIT_ATR" },
|
||||||
|
{ ISO_S_IN_ATR, "IN_ATR" },
|
||||||
|
{ ISO_S_IN_PTS, "IN_PTS" },
|
||||||
|
{ ISO_S_WAIT_TPDU, "WAIT_TPDU" },
|
||||||
|
{ ISO_S_IN_TPDU, "IN_TPDU" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* detailed sub-states of ISO_S_IN_PTS */
|
/* detailed sub-states of ISO_S_IN_PTS */
|
||||||
enum pts_state {
|
enum pts_state {
|
||||||
PTS_S_WAIT_REQ_PTSS,
|
PTS_S_WAIT_REQ_PTSS,
|
||||||
@@ -72,6 +86,23 @@ enum pts_state {
|
|||||||
PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
|
PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct value_string pts_state_names[] = {
|
||||||
|
{ PTS_S_WAIT_REQ_PTSS, "WAIT_REQ_PTSS" },
|
||||||
|
{ PTS_S_WAIT_REQ_PTS0, "WAIT_REQ_PTS0" },
|
||||||
|
{ PTS_S_WAIT_REQ_PTS1, "WAIT_REQ_PTS1" },
|
||||||
|
{ PTS_S_WAIT_REQ_PTS2, "WAIT_REQ_PTS2" },
|
||||||
|
{ PTS_S_WAIT_REQ_PTS3, "WAIT_REQ_PTS3" },
|
||||||
|
{ PTS_S_WAIT_REQ_PCK, "WAIT_REQ_PCK" },
|
||||||
|
{ PTS_S_WAIT_RESP_PTSS, "WAIT_RESP_PTSS" },
|
||||||
|
{ PTS_S_WAIT_RESP_PTS0, "WAIT_RESP_PTS0" },
|
||||||
|
{ PTS_S_WAIT_RESP_PTS1, "WAIT_RESP_PTS1" },
|
||||||
|
{ PTS_S_WAIT_RESP_PTS2, "WAIT_RESP_PTS2" },
|
||||||
|
{ PTS_S_WAIT_RESP_PTS3, "WAIT_RESP_PTS3" },
|
||||||
|
{ PTS_S_WAIT_RESP_PCK, "WAIT_RESP_PCK" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PTS field byte index */
|
||||||
#define _PTSS 0
|
#define _PTSS 0
|
||||||
#define _PTS0 1
|
#define _PTS0 1
|
||||||
#define _PTS1 2
|
#define _PTS1 2
|
||||||
@@ -87,10 +118,23 @@ enum tpdu_state {
|
|||||||
TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
|
TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
|
||||||
TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
|
TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
|
||||||
TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
|
TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
|
||||||
TPDU_S_WAIT_RX, /* waiitng for more data from reader */
|
TPDU_S_WAIT_RX, /* waiting for more data from reader */
|
||||||
TPDU_S_WAIT_TX, /* waiting for more data to reader */
|
TPDU_S_WAIT_TX, /* waiting for more data to reader */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct value_string tpdu_state_names[] = {
|
||||||
|
{ TPDU_S_WAIT_CLA, "WAIT_CLA" },
|
||||||
|
{ TPDU_S_WAIT_INS, "WAIT_INS" },
|
||||||
|
{ TPDU_S_WAIT_P1, "WAIT_P1" },
|
||||||
|
{ TPDU_S_WAIT_P2, "WAIT_P2" },
|
||||||
|
{ TPDU_S_WAIT_P3, "WAIT_P3" },
|
||||||
|
{ TPDU_S_WAIT_PB, "WAIT_PB" },
|
||||||
|
{ TPDU_S_WAIT_RX, "WAIT_RX" },
|
||||||
|
{ TPDU_S_WAIT_TX, "WAIT_TX" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* TPDU field byte index */
|
||||||
#define _CLA 0
|
#define _CLA 0
|
||||||
#define _INS 1
|
#define _INS 1
|
||||||
#define _P1 2
|
#define _P1 2
|
||||||
@@ -98,14 +142,17 @@ enum tpdu_state {
|
|||||||
#define _P3 4
|
#define _P3 4
|
||||||
|
|
||||||
struct card_handle {
|
struct card_handle {
|
||||||
uint32_t num;
|
unsigned int num;
|
||||||
|
|
||||||
|
/* bit-mask of enabled optional features (CEMU_FEAT_F_*) */
|
||||||
|
uint32_t features;
|
||||||
|
|
||||||
enum iso7816_3_card_state state;
|
enum iso7816_3_card_state state;
|
||||||
|
|
||||||
/* signal levels */
|
/* signal levels */
|
||||||
uint8_t vcc_active; /* 1 = on, 0 = off */
|
bool vcc_active; /*< if VCC is active (true = active/ON) */
|
||||||
uint8_t in_reset; /* 1 = RST low, 0 = RST high */
|
bool in_reset; /*< if card is in reset (true = RST low/asserted, false = RST high/ released) */
|
||||||
uint8_t clocked; /* 1 = active, 0 = inactive */
|
bool clocked; /*< if clock is active ( true = active, false = inactive) */
|
||||||
|
|
||||||
/* timing parameters, from PTS */
|
/* timing parameters, from PTS */
|
||||||
uint8_t fi;
|
uint8_t fi;
|
||||||
@@ -154,6 +201,27 @@ struct card_handle {
|
|||||||
} stats;
|
} stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* reset all the 'dynamic' state of the card handle to the initial/default values */
|
||||||
|
static void card_handle_reset(struct card_handle *ch)
|
||||||
|
{
|
||||||
|
struct msgb *msg;
|
||||||
|
|
||||||
|
tc_etu_disable(ch->tc_chan);
|
||||||
|
|
||||||
|
/* release any buffers we may still own */
|
||||||
|
if (ch->uart_tx_msg) {
|
||||||
|
usb_buf_free(ch->uart_tx_msg);
|
||||||
|
ch->uart_tx_msg = NULL;
|
||||||
|
}
|
||||||
|
if (ch->uart_rx_msg) {
|
||||||
|
usb_buf_free(ch->uart_rx_msg);
|
||||||
|
ch->uart_rx_msg = NULL;
|
||||||
|
}
|
||||||
|
while ((msg = msgb_dequeue(&ch->uart_tx_queue))) {
|
||||||
|
usb_buf_free(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
|
struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
|
||||||
{
|
{
|
||||||
return &ch->uart_tx_queue;
|
return &ch->uart_tx_queue;
|
||||||
@@ -175,12 +243,35 @@ void usb_buf_upd_len_and_submit(struct msgb *msg)
|
|||||||
/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
|
/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
|
||||||
struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
|
struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
|
||||||
{
|
{
|
||||||
struct msgb *msg;
|
struct msgb *msg = NULL;
|
||||||
struct simtrace_msg_hdr *sh;
|
struct simtrace_msg_hdr *sh;
|
||||||
|
|
||||||
msg = usb_buf_alloc(ep);
|
while (!msg) {
|
||||||
if (!msg)
|
msg = usb_buf_alloc(ep); // try to allocate some memory
|
||||||
return NULL;
|
if (!msg) { // allocation failed, we might be out of memory
|
||||||
|
struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
|
||||||
|
if (!bep) {
|
||||||
|
TRACE_ERROR("ep %u: %s queue does not exist\n\r",
|
||||||
|
ep, __func__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (llist_empty(&bep->queue)) {
|
||||||
|
TRACE_ERROR("ep %u: %s EOMEM (queue already empty)\n\r",
|
||||||
|
ep, __func__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
msg = msgb_dequeue_count(&bep->queue, &bep->queue_len);
|
||||||
|
if (!msg) {
|
||||||
|
TRACE_ERROR("ep %u: %s no msg in non-empty queue\n\r",
|
||||||
|
ep, __func__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
usb_buf_free(msg);
|
||||||
|
msg = NULL;
|
||||||
|
TRACE_DEBUG("ep %u: %s queue msg dropped\n\r",
|
||||||
|
ep, __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
msg->l1h = msgb_put(msg, sizeof(*sh));
|
msg->l1h = msgb_put(msg, sizeof(*sh));
|
||||||
sh = (struct simtrace_msg_hdr *) msg->l1h;
|
sh = (struct simtrace_msg_hdr *) msg->l1h;
|
||||||
@@ -192,7 +283,7 @@ struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update cardemu_usb_msg_rx_data length + submit bufffer */
|
/* Update cardemu_usb_msg_rx_data length + submit buffer */
|
||||||
static void flush_rx_buffer(struct card_handle *ch)
|
static void flush_rx_buffer(struct card_handle *ch)
|
||||||
{
|
{
|
||||||
struct msgb *msg;
|
struct msgb *msg;
|
||||||
@@ -205,14 +296,17 @@ static void flush_rx_buffer(struct card_handle *ch)
|
|||||||
|
|
||||||
ch->uart_rx_msg = NULL;
|
ch->uart_rx_msg = NULL;
|
||||||
|
|
||||||
/* store length of data payload fild in header */
|
/* store length of data payload field in header */
|
||||||
rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
|
rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
|
||||||
rd->data_len = msgb_l2len(msg) - sizeof(*rd);
|
rd->data_len = msgb_l2len(msg) - sizeof(*rd);
|
||||||
|
|
||||||
|
TRACE_INFO("%u: %s (%u)\n\r",
|
||||||
|
ch->num, __func__, rd->data_len);
|
||||||
|
|
||||||
usb_buf_upd_len_and_submit(msg);
|
usb_buf_upd_len_and_submit(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert a non-contiguous PTS request/responsei into a contiguous
|
/* convert a non-contiguous PTS request/response into a contiguous
|
||||||
* buffer, returning the number of bytes used in the buffer */
|
* buffer, returning the number of bytes used in the buffer */
|
||||||
static int serialize_pts(uint8_t *out, const uint8_t *in)
|
static int serialize_pts(uint8_t *out, const uint8_t *in)
|
||||||
{
|
{
|
||||||
@@ -287,8 +381,9 @@ static void card_set_state(struct card_handle *ch,
|
|||||||
if (ch->state == new_state)
|
if (ch->state == new_state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TRACE_DEBUG("%u: 7816 card state %u -> %u\r\n", ch->num,
|
TRACE_DEBUG("%u: 7816 card state %s -> %s\r\n", ch->num,
|
||||||
ch->state, new_state);
|
get_value_string(iso7816_3_card_state_names, ch->state),
|
||||||
|
get_value_string(iso7816_3_card_state_names, new_state));
|
||||||
ch->state = new_state;
|
ch->state = new_state;
|
||||||
|
|
||||||
switch (new_state) {
|
switch (new_state) {
|
||||||
@@ -299,32 +394,39 @@ static void card_set_state(struct card_handle *ch,
|
|||||||
card_emu_uart_enable(ch->uart_chan, 0);
|
card_emu_uart_enable(ch->uart_chan, 0);
|
||||||
break;
|
break;
|
||||||
case ISO_S_WAIT_ATR:
|
case ISO_S_WAIT_ATR:
|
||||||
set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
|
|
||||||
/* Reset to initial Fi / Di ratio */
|
/* Reset to initial Fi / Di ratio */
|
||||||
ch->fi = 1;
|
ch->fi = 1;
|
||||||
ch->di = 1;
|
ch->di = 1;
|
||||||
emu_update_fidi(ch);
|
emu_update_fidi(ch);
|
||||||
/* initialize todefault WI, this will be overwritten if we
|
/* the ATR should only be sent 400 to 40k clock cycles after the RESET.
|
||||||
* receive TC2, and it will be programmed into hardware after
|
* we use the tc_etu mechanism to wait this time.
|
||||||
|
* since the initial ETU is Fd=372/Dd=1 clock cycles long, we have to wait 2-107 ETU.
|
||||||
|
*/
|
||||||
|
tc_etu_set_wtime(ch->tc_chan, 2);
|
||||||
|
/* enable the TC/ETU counter once reset has been released */
|
||||||
|
tc_etu_enable(ch->tc_chan);
|
||||||
|
break;
|
||||||
|
case ISO_S_IN_ATR:
|
||||||
|
/* initialize to default WI, this will be overwritten if we
|
||||||
|
* send TC2, and it will be programmed into hardware after
|
||||||
* ATR is finished */
|
* ATR is finished */
|
||||||
ch->wi = ISO7816_3_DEFAULT_WI;
|
ch->wi = ISO7816_3_DEFAULT_WI;
|
||||||
/* update waiting time to initial waiting time */
|
/* update waiting time to initial waiting time */
|
||||||
ch->waiting_time = ISO7816_3_INIT_WTIME;
|
ch->waiting_time = ISO7816_3_INIT_WTIME;
|
||||||
|
/* set initial waiting time */
|
||||||
tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
|
tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
|
||||||
/* Set ATR sub-state to initial state */
|
/* Set ATR sub-state to initial state */
|
||||||
ch->atr.idx = 0;
|
ch->atr.idx = 0;
|
||||||
//set_atr_state(ch, ATR_S_WAIT_TS);
|
/* enable USART transmission to reader */
|
||||||
/* Notice that we are just coming out of reset */
|
|
||||||
//ch->sh.flags |= SIMTRACE_FLAG_ATR;
|
|
||||||
card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
|
card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
|
||||||
break;
|
/* trigger USART TX IRQ to sent first ATR byte TS */
|
||||||
|
card_emu_uart_interrupt(ch->uart_chan);
|
||||||
break;
|
break;
|
||||||
case ISO_S_WAIT_TPDU:
|
case ISO_S_WAIT_TPDU:
|
||||||
/* enable the receiver, disable transmitter */
|
/* enable the receiver, disable transmitter */
|
||||||
set_tpdu_state(ch, TPDU_S_WAIT_CLA);
|
set_tpdu_state(ch, TPDU_S_WAIT_CLA);
|
||||||
card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
|
card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
|
||||||
break;
|
break;
|
||||||
case ISO_S_IN_ATR:
|
|
||||||
case ISO_S_IN_PTS:
|
case ISO_S_IN_PTS:
|
||||||
case ISO_S_IN_TPDU:
|
case ISO_S_IN_TPDU:
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
@@ -332,16 +434,83 @@ static void card_set_state(struct card_handle *ch,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* ATR handling
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
/*! Transmit ATR data to reader
|
||||||
|
* @param[in] ch card interface connected to reader
|
||||||
|
* @return numbers of bytes transmitted
|
||||||
|
*/
|
||||||
|
static int tx_byte_atr(struct card_handle *ch)
|
||||||
|
{
|
||||||
|
if (NULL == ch) {
|
||||||
|
TRACE_ERROR("ATR TX: no card handle provided\n\r");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ISO_S_IN_ATR != ch->state) {
|
||||||
|
TRACE_ERROR("%u: ATR TX: no in ATR state\n\r", ch->num);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transmit ATR */
|
||||||
|
if (ch->atr.idx < ch->atr.len) {
|
||||||
|
uint8_t byte = ch->atr.atr[ch->atr.idx++];
|
||||||
|
card_emu_uart_tx(ch->uart_chan, byte);
|
||||||
|
return 1;
|
||||||
|
} else { /* The ATR has been completely transmitted */
|
||||||
|
/* search for TC2 to updated WI */
|
||||||
|
ch->wi = ISO7816_3_DEFAULT_WI;
|
||||||
|
if (ch->atr.len >= 2 && ch->atr.atr[1] & 0xf0) { /* Y1 has some data */
|
||||||
|
uint8_t atr_td1 = 2;
|
||||||
|
if (ch->atr.atr[1] & 0x10) { /* TA1 is present */
|
||||||
|
atr_td1++;
|
||||||
|
}
|
||||||
|
if (ch->atr.atr[1] & 0x20) { /* TB1 is present */
|
||||||
|
atr_td1++;
|
||||||
|
}
|
||||||
|
if (ch->atr.atr[1] & 0x40) { /* TC1 is present */
|
||||||
|
atr_td1++;
|
||||||
|
}
|
||||||
|
if (ch->atr.atr[1] & 0x80) { /* TD1 is present */
|
||||||
|
if (ch->atr.len > atr_td1 && ch->atr.atr[atr_td1] & 0xf0) { /* Y2 has some data */
|
||||||
|
uint8_t atr_tc2 = atr_td1+1;
|
||||||
|
if (ch->atr.atr[atr_td1] & 0x10) { /* TA2 is present */
|
||||||
|
atr_tc2++;
|
||||||
|
}
|
||||||
|
if (ch->atr.atr[atr_td1] & 0x20) { /* TB2 is present */
|
||||||
|
atr_tc2++;
|
||||||
|
}
|
||||||
|
if (ch->atr.atr[atr_td1] & 0x40) { /* TC2 is present */
|
||||||
|
if (ch->atr.len > atr_tc2 && ch->atr.atr[atr_tc2]) { /* TC2 encodes WI */
|
||||||
|
ch->wi = ch->atr.atr[atr_tc2]; /* set WI */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* update waiting time (see ISO 7816-3 10.2) */
|
||||||
|
ch->waiting_time = ch->wi * 960 * ch->fi;
|
||||||
|
tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
|
||||||
|
/* go to next state */
|
||||||
|
card_set_state(ch, ISO_S_WAIT_TPDU);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return number of bytes transmitted */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* PTS / PPS handling
|
* PTS / PPS handling
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
/* Update the ATR sub-state */
|
/* Update the PTS sub-state */
|
||||||
static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
|
static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
|
||||||
{
|
{
|
||||||
TRACE_DEBUG("%u: 7816 PTS state %u -> %u\r\n",
|
TRACE_DEBUG("%u: 7816 PTS state %s -> %s\r\n", ch->num,
|
||||||
ch->num, ch->pts.state, new_ptss);
|
get_value_string(pts_state_names, ch->pts.state),
|
||||||
|
get_value_string(pts_state_names, new_ptss));
|
||||||
ch->pts.state = new_ptss;
|
ch->pts.state = new_ptss;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,8 +590,8 @@ process_byte_pts(struct card_handle *ch, uint8_t byte)
|
|||||||
memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
|
memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE_ERROR("%u: process_byte_pts() in invalid state %u\r\n",
|
TRACE_ERROR("%u: process_byte_pts() in invalid PTS state %s\r\n", ch->num,
|
||||||
ch->num, ch->pts.state);
|
get_value_string(pts_state_names, ch->pts.state));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* calculate the next state and set it */
|
/* calculate the next state and set it */
|
||||||
@@ -472,8 +641,8 @@ static int tx_byte_pts(struct card_handle *ch)
|
|||||||
byte = ch->pts.resp[_PCK];
|
byte = ch->pts.resp[_PCK];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE_ERROR("%u: get_byte_pts() in invalid state %u\r\n",
|
TRACE_ERROR("%u: get_byte_pts() in invalid PTS state %s\r\n", ch->num,
|
||||||
ch->num, ch->pts.state);
|
get_value_string(pts_state_names, ch->pts.state));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +658,6 @@ static int tx_byte_pts(struct card_handle *ch)
|
|||||||
emu_update_fidi(ch);
|
emu_update_fidi(ch);
|
||||||
/* Wait for the next TPDU */
|
/* Wait for the next TPDU */
|
||||||
card_set_state(ch, ISO_S_WAIT_TPDU);
|
card_set_state(ch, ISO_S_WAIT_TPDU);
|
||||||
set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* calculate the next state and set it */
|
/* calculate the next state and set it */
|
||||||
@@ -558,9 +726,9 @@ static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
|
|||||||
if (ch->tpdu.state == new_ts)
|
if (ch->tpdu.state == new_ts)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TRACE_DEBUG("%u: 7816 TPDU state %u -> %u\r\n", ch->num,
|
TRACE_DEBUG("%u: 7816 TPDU state %s -> %s\r\n", ch->num,
|
||||||
ch->tpdu.state, new_ts);
|
get_value_string(tpdu_state_names, ch->tpdu.state),
|
||||||
|
get_value_string(tpdu_state_names, new_ts));
|
||||||
ch->tpdu.state = new_ts;
|
ch->tpdu.state = new_ts;
|
||||||
|
|
||||||
switch (new_ts) {
|
switch (new_ts) {
|
||||||
@@ -679,8 +847,8 @@ process_byte_tpdu(struct card_handle *ch, uint8_t byte)
|
|||||||
add_tpdu_byte(ch, byte);
|
add_tpdu_byte(ch, byte);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE_ERROR("%u: process_byte_tpdu() in invalid state %u\r\n",
|
TRACE_ERROR("%u: process_byte_tpdu() in invalid TPDU state %s\r\n", ch->num,
|
||||||
ch->num, ch->tpdu.state);
|
get_value_string(tpdu_state_names, ch->tpdu.state));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ensure we stay in TPDU ISO state */
|
/* ensure we stay in TPDU ISO state */
|
||||||
@@ -718,7 +886,7 @@ static int tx_byte_tpdu(struct card_handle *ch)
|
|||||||
|
|
||||||
card_emu_uart_tx(ch->uart_chan, byte);
|
card_emu_uart_tx(ch->uart_chan, byte);
|
||||||
|
|
||||||
/* this must happen _after_ the byte has been transmittd */
|
/* this must happen _after_ the byte has been transmitted */
|
||||||
switch (ch->tpdu.state) {
|
switch (ch->tpdu.state) {
|
||||||
case TPDU_S_WAIT_PB:
|
case TPDU_S_WAIT_PB:
|
||||||
/* if we just transmitted the procedure byte, we need to decide
|
/* if we just transmitted the procedure byte, we need to decide
|
||||||
@@ -765,16 +933,10 @@ void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
|
|||||||
ch->stats.rx_bytes++;
|
ch->stats.rx_bytes++;
|
||||||
|
|
||||||
switch (ch->state) {
|
switch (ch->state) {
|
||||||
case ISO_S_WAIT_POWER:
|
|
||||||
case ISO_S_WAIT_CLK:
|
|
||||||
case ISO_S_WAIT_RST:
|
|
||||||
case ISO_S_WAIT_ATR:
|
|
||||||
TRACE_ERROR("%u: Received UART char in invalid 7816 state "
|
|
||||||
"%u\r\n", ch->num, ch->state);
|
|
||||||
/* we shouldn't receive any data from the reader yet! */
|
|
||||||
break;
|
|
||||||
case ISO_S_WAIT_TPDU:
|
case ISO_S_WAIT_TPDU:
|
||||||
if (byte == 0xff) {
|
if (byte == 0xff) {
|
||||||
|
/* reset PTS to initial state */
|
||||||
|
set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
|
||||||
new_state = process_byte_pts(ch, byte);
|
new_state = process_byte_pts(ch, byte);
|
||||||
ch->stats.pps++;
|
ch->stats.pps++;
|
||||||
goto out_silent;
|
goto out_silent;
|
||||||
@@ -786,6 +948,10 @@ void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
|
|||||||
case ISO_S_IN_PTS:
|
case ISO_S_IN_PTS:
|
||||||
new_state = process_byte_pts(ch, byte);
|
new_state = process_byte_pts(ch, byte);
|
||||||
goto out_silent;
|
goto out_silent;
|
||||||
|
default:
|
||||||
|
TRACE_ERROR("%u: Received UART char in invalid 7816 state %s\r\n", ch->num,
|
||||||
|
get_value_string(iso7816_3_card_state_names, ch->state));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_silent:
|
out_silent:
|
||||||
@@ -800,17 +966,7 @@ int card_emu_tx_byte(struct card_handle *ch)
|
|||||||
|
|
||||||
switch (ch->state) {
|
switch (ch->state) {
|
||||||
case ISO_S_IN_ATR:
|
case ISO_S_IN_ATR:
|
||||||
if (ch->atr.idx < ch->atr.len) {
|
rc = tx_byte_atr(ch);
|
||||||
uint8_t byte;
|
|
||||||
byte = ch->atr.atr[ch->atr.idx++];
|
|
||||||
rc = 1;
|
|
||||||
|
|
||||||
card_emu_uart_tx(ch->uart_chan, byte);
|
|
||||||
|
|
||||||
/* detect end of ATR */
|
|
||||||
if (ch->atr.idx >= ch->atr.len)
|
|
||||||
card_set_state(ch, ISO_S_WAIT_TPDU);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ISO_S_IN_PTS:
|
case ISO_S_IN_PTS:
|
||||||
rc = tx_byte_pts(ch);
|
rc = tx_byte_pts(ch);
|
||||||
@@ -847,13 +1003,16 @@ void card_emu_have_new_uart_tx(struct card_handle *ch)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void card_emu_report_status(struct card_handle *ch)
|
void card_emu_report_status(struct card_handle *ch, bool report_on_irq)
|
||||||
{
|
{
|
||||||
struct msgb *msg;
|
struct msgb *msg;
|
||||||
struct cardemu_usb_msg_status *sts;
|
struct cardemu_usb_msg_status *sts;
|
||||||
|
uint8_t ep = ch->in_ep;
|
||||||
|
|
||||||
msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
|
if (report_on_irq)
|
||||||
SIMTRACE_MSGT_BD_CEMU_STATUS);
|
ep = ch->irq_ep;
|
||||||
|
|
||||||
|
msg = usb_buf_alloc_st(ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_BD_CEMU_STATUS);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -874,18 +1033,38 @@ void card_emu_report_status(struct card_handle *ch)
|
|||||||
usb_buf_upd_len_and_submit(msg);
|
usb_buf_upd_len_and_submit(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void card_emu_report_config(struct card_handle *ch)
|
||||||
|
{
|
||||||
|
struct msgb *msg;
|
||||||
|
struct cardemu_usb_msg_config *cfg;
|
||||||
|
uint8_t ep = ch->in_ep;
|
||||||
|
|
||||||
|
msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_BD_CEMU_CONFIG);
|
||||||
|
if (!msg)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cfg = (struct cardemu_usb_msg_config *) msgb_put(msg, sizeof(*cfg));
|
||||||
|
cfg->features = ch->features;
|
||||||
|
|
||||||
|
usb_buf_upd_len_and_submit(msg);
|
||||||
|
}
|
||||||
|
|
||||||
/* hardware driver informs us that a card I/O signal has changed */
|
/* hardware driver informs us that a card I/O signal has changed */
|
||||||
void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
|
void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
|
||||||
{
|
{
|
||||||
|
uint32_t chg_mask = 0;
|
||||||
|
|
||||||
switch (io) {
|
switch (io) {
|
||||||
case CARD_IO_VCC:
|
case CARD_IO_VCC:
|
||||||
if (active == 0 && ch->vcc_active == 1) {
|
if (active == 0 && ch->vcc_active == 1) {
|
||||||
TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
|
TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
|
||||||
tc_etu_disable(ch->tc_chan);
|
card_handle_reset(ch);
|
||||||
card_set_state(ch, ISO_S_WAIT_POWER);
|
card_set_state(ch, ISO_S_WAIT_POWER);
|
||||||
|
chg_mask |= CEMU_STATUS_F_VCC_PRESENT;
|
||||||
} else if (active == 1 && ch->vcc_active == 0) {
|
} else if (active == 1 && ch->vcc_active == 0) {
|
||||||
TRACE_INFO("%u: VCC activated\r\n", ch->num);
|
TRACE_INFO("%u: VCC activated\r\n", ch->num);
|
||||||
card_set_state(ch, ISO_S_WAIT_CLK);
|
card_set_state(ch, ISO_S_WAIT_CLK);
|
||||||
|
chg_mask |= CEMU_STATUS_F_VCC_PRESENT;
|
||||||
}
|
}
|
||||||
ch->vcc_active = active;
|
ch->vcc_active = active;
|
||||||
break;
|
break;
|
||||||
@@ -894,8 +1073,10 @@ void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
|
|||||||
TRACE_INFO("%u: CLK activated\r\n", ch->num);
|
TRACE_INFO("%u: CLK activated\r\n", ch->num);
|
||||||
if (ch->state == ISO_S_WAIT_CLK)
|
if (ch->state == ISO_S_WAIT_CLK)
|
||||||
card_set_state(ch, ISO_S_WAIT_RST);
|
card_set_state(ch, ISO_S_WAIT_RST);
|
||||||
|
chg_mask |= CEMU_STATUS_F_CLK_ACTIVE;
|
||||||
} else if (active == 0 && ch->clocked == 1) {
|
} else if (active == 0 && ch->clocked == 1) {
|
||||||
TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
|
TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
|
||||||
|
chg_mask |= CEMU_STATUS_F_CLK_ACTIVE;
|
||||||
}
|
}
|
||||||
ch->clocked = active;
|
ch->clocked = active;
|
||||||
break;
|
break;
|
||||||
@@ -905,17 +1086,37 @@ void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
|
|||||||
if (ch->vcc_active && ch->clocked) {
|
if (ch->vcc_active && ch->clocked) {
|
||||||
/* enable the TC/ETU counter once reset has been released */
|
/* enable the TC/ETU counter once reset has been released */
|
||||||
tc_etu_enable(ch->tc_chan);
|
tc_etu_enable(ch->tc_chan);
|
||||||
|
/* prepare to send the ATR */
|
||||||
card_set_state(ch, ISO_S_WAIT_ATR);
|
card_set_state(ch, ISO_S_WAIT_ATR);
|
||||||
/* FIXME: wait 400 to 40k clock cycles before sending ATR */
|
|
||||||
card_set_state(ch, ISO_S_IN_ATR);
|
|
||||||
}
|
}
|
||||||
|
chg_mask |= CEMU_STATUS_F_RESET_ACTIVE;
|
||||||
} else if (active && !ch->in_reset) {
|
} else if (active && !ch->in_reset) {
|
||||||
TRACE_INFO("%u: RST asserted\r\n", ch->num);
|
TRACE_INFO("%u: RST asserted\r\n", ch->num);
|
||||||
tc_etu_disable(ch->tc_chan);
|
card_handle_reset(ch);
|
||||||
|
chg_mask |= CEMU_STATUS_F_RESET_ACTIVE;
|
||||||
}
|
}
|
||||||
ch->in_reset = active;
|
ch->in_reset = active;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (ch->state) {
|
||||||
|
case ISO_S_WAIT_POWER:
|
||||||
|
case ISO_S_WAIT_CLK:
|
||||||
|
case ISO_S_WAIT_RST:
|
||||||
|
/* check end activation state (even if the reader does
|
||||||
|
* not respect the activation sequence) */
|
||||||
|
if (ch->vcc_active && ch->clocked && !ch->in_reset) {
|
||||||
|
/* prepare to send the ATR */
|
||||||
|
card_set_state(ch, ISO_S_WAIT_ATR);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* notify the host about the state change */
|
||||||
|
if ((ch->features & CEMU_FEAT_F_STATUS_IRQ) && chg_mask)
|
||||||
|
card_emu_report_status(ch, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* User sets a new ATR to be returned during next card reset */
|
/* User sets a new ATR to be returned during next card reset */
|
||||||
@@ -928,7 +1129,15 @@ int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
|
|||||||
ch->atr.len = len;
|
ch->atr.len = len;
|
||||||
ch->atr.idx = 0;
|
ch->atr.idx = 0;
|
||||||
|
|
||||||
/* FIXME: race condition with trasmitting ATR to reader? */
|
#if TRACE_LEVEL >= TRACE_LEVEL_INFO
|
||||||
|
uint8_t i;
|
||||||
|
TRACE_INFO("%u: ATR set: ", ch->num);
|
||||||
|
for (i = 0; i < ch->atr.len; i++) {
|
||||||
|
TRACE_INFO_WP("%02x ", atr[i]);
|
||||||
|
}
|
||||||
|
TRACE_INFO_WP("\n\r");
|
||||||
|
#endif
|
||||||
|
/* FIXME: race condition with transmitting ATR to reader? */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -959,16 +1168,35 @@ void tc_etu_wtime_half_expired(void *handle)
|
|||||||
void tc_etu_wtime_expired(void *handle)
|
void tc_etu_wtime_expired(void *handle)
|
||||||
{
|
{
|
||||||
struct card_handle *ch = handle;
|
struct card_handle *ch = handle;
|
||||||
TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
|
switch (ch->state) {
|
||||||
|
case ISO_S_WAIT_ATR:
|
||||||
|
/* ISO 7816-3 6.2.1 time tc has passed, we can now send the ATR */
|
||||||
|
card_set_state(ch, ISO_S_IN_ATR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* shortest ATR found in smartcard_list.txt */
|
/* shortest ATR possible (uses default speed and no options) */
|
||||||
static const uint8_t default_atr[] = { 0x3B, 0x02, 0x14, 0x50 };
|
static const uint8_t default_atr[] = { 0x3B, 0x00 };
|
||||||
|
|
||||||
static struct card_handle card_handles[NUM_SLOTS];
|
static struct card_handle card_handles[NUM_SLOTS];
|
||||||
|
|
||||||
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan,
|
int card_emu_set_config(struct card_handle *ch, const struct cardemu_usb_msg_config *scfg,
|
||||||
uint8_t in_ep, uint8_t irq_ep)
|
unsigned int scfg_len)
|
||||||
|
{
|
||||||
|
if (scfg_len >= sizeof(uint32_t))
|
||||||
|
ch->features = (scfg->features & SUPPORTED_FEATURES);
|
||||||
|
|
||||||
|
/* send back a report of our current configuration */
|
||||||
|
card_emu_report_config(ch);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked)
|
||||||
{
|
{
|
||||||
struct card_handle *ch;
|
struct card_handle *ch;
|
||||||
|
|
||||||
@@ -981,14 +1209,13 @@ struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uar
|
|||||||
|
|
||||||
INIT_LLIST_HEAD(&ch->uart_tx_queue);
|
INIT_LLIST_HEAD(&ch->uart_tx_queue);
|
||||||
|
|
||||||
/* initialize the card_handle with reasonabe defaults */
|
|
||||||
ch->num = slot_num;
|
ch->num = slot_num;
|
||||||
ch->irq_ep = irq_ep;
|
ch->irq_ep = irq_ep;
|
||||||
ch->in_ep = in_ep;
|
ch->in_ep = in_ep;
|
||||||
ch->state = ISO_S_WAIT_POWER;
|
ch->state = ISO_S_WAIT_POWER;
|
||||||
ch->vcc_active = 0;
|
ch->vcc_active = vcc_active;
|
||||||
ch->in_reset = 1;
|
ch->in_reset = in_reset;
|
||||||
ch->clocked = 0;
|
ch->clocked = clocked;
|
||||||
|
|
||||||
ch->fi = 0;
|
ch->fi = 0;
|
||||||
ch->di = 1;
|
ch->di = 1;
|
||||||
@@ -1002,8 +1229,7 @@ struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uar
|
|||||||
ch->atr.len = sizeof(default_atr);
|
ch->atr.len = sizeof(default_atr);
|
||||||
memcpy(ch->atr.atr, default_atr, ch->atr.len);
|
memcpy(ch->atr.atr, default_atr, ch->atr.len);
|
||||||
|
|
||||||
ch->pts.state = PTS_S_WAIT_REQ_PTSS;
|
card_handle_reset(ch);
|
||||||
ch->tpdu.state = TPDU_S_WAIT_CLA;
|
|
||||||
|
|
||||||
tc_etu_init(ch->tc_chan, ch);
|
tc_etu_init(ch->tc_chan, ch);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user