Compare commits

...

136 Commits

Author SHA1 Message Date
Ben V. Brown
d75f361c4e Version bump 2020-09-06 17:55:51 +10:00
Ben V. Brown
e3e839f960 Merge pull request #692 from Ralim/cleanup_menu
Cleanup menu
2020-09-06 17:17:51 +10:00
Ben V. Brown
d50a733250 Cull single line menu options from json languages 2020-09-06 16:44:31 +10:00
Ben V. Brown
aa78ca2594 Dropping single line menu support 2020-09-06 16:44:19 +10:00
Ben V. Brown
c7bde079cd Update Settings.h 2020-09-06 16:11:53 +10:00
Ben V. Brown
99ba13525a Collapse Boost temp enable into setting
Work for #642
2020-09-06 16:04:41 +10:00
Ben V. Brown
feec35be7a Collapse power limiter into one menu option
Work for #642
2020-09-06 15:31:23 +10:00
Ben V. Brown
5459d437e4 Merge pull request #661 from paulfertser/last-value-pause
Add a pause for the last value in settings menus
2020-09-06 14:24:53 +10:00
Ben V. Brown
4925e074ca Merge pull request #691 from Ralim/docs
Remove old codeship + docs updates
2020-09-06 14:14:49 +10:00
Ben V. Brown
30c470cbf1 Remove old codeship + docs updates 2020-09-06 14:00:35 +10:00
Ben V. Brown
f5bc1e15b5 CI performance (#690)
More CI performance increase

* Runs all builds in parallel
* Avoids using the extra docker container in CI
2020-09-06 13:28:24 +10:00
Ben V. Brown
04b4f2a3ed Merge pull request #689 from Ralim/ci-tweak
Move artefact outputs to be done per model
2020-09-06 11:25:52 +10:00
Ben V. Brown
8a4b0af44d Testing 2020-09-06 11:10:06 +10:00
Ben V. Brown
aa51c62bdf Merge pull request #686 from Ralim/looking_at_i2c
Fixing up a load bearing bug in the i2c setup (and fixing up some PD logic for free)
2020-09-06 11:05:39 +10:00
Ben V. Brown
ed0675a549 Merge branch 'master' into looking_at_i2c 2020-09-06 10:40:29 +10:00
Ben V. Brown
a1bd53f85a Merge pull request #687 from paulfertser/lto-build-improvements
Fix FTBFS due to LTO being more sensitive to file order
2020-09-06 10:40:16 +10:00
Paul Fertser
e6e0a0f280 Makefile: remove -ffat-lto-objects
"Fat" LTO objects are only needed if future linking _without_ LTO is
planned. Not using this option gives about 1.5x building time advantage
without affecting the final binary.

An unused variable is removed along the way.
2020-09-05 18:48:36 +03:00
Paul Fertser
d37f8def88 Fix FTBFS due to LTO being more sensitive to file order
When a symbol is used from inline assembly, LTO compiling and linking
process becomes more picky with regard to the order of compile/linking
units.

Specifically, when FreeRTOS/Source/portable/GCC/ARM_CM3/port.c comes
before FreeRTOS/Source/tasks.c in find results, the build fails with
undefined reference to `pxCurrentTCB' error.

To workaround the issue, do the same as we already have for
vTaskSwitchContext.

Note: different order affects resulting binary (.text section) size:
39924 with the wrong order and 39884 with the correct.

Fixes #685.
2020-09-05 18:45:40 +03:00
Ben V. Brown
023e176c87 Update int_n.cpp 2020-09-05 20:29:57 +10:00
Ben V. Brown
8bacbe49fc Bring back PD 3.0 2020-09-05 20:26:07 +10:00
Ben V. Brown
12cf202338 Remove reset handler 2020-09-05 20:19:12 +10:00
Ben V. Brown
11e583be63 Fix interrupt race 2020-09-05 20:19:03 +10:00
Ben V. Brown
d48b27928a Move I2C initalisations into more logical spots 2020-09-05 20:10:10 +10:00
Ben V. Brown
d9c05db058 I2C wrapper cleanup 2020-09-05 20:04:07 +10:00
Ben V. Brown
372f8e3565 Update Dockerfile 2020-08-29 14:39:46 +10:00
Ben V. Brown
3d3799d414 Prepare v2.11 release 2020-08-29 14:38:56 +10:00
Paul Fertser
a2a23b575f Pause for the last value in settings menus and blink the scroll thumb
This radically slows down auto-incrementing (when the change button is
kept pressed) of values when user reaches the maximum (last) allowed
option. The scrollbar thumb is blinking to indicate to the user that the
next keypress will wraparound (unless this value was already active
prior to entering menu).

Fixes #536.
2020-08-28 13:13:42 +03:00
Paul Fertser
1d63a3d7bc Fix temp change long step MAX value
There is no space on the screen to output 3 digits, and the
corresponding display function assumes the value is less than 100.
2020-08-28 13:13:41 +03:00
Paul Fertser
a64186d9a4 Fix key autorepeat timing
This constant is in scheduler ticks so needs to be changed accordingly
to keep the old timing.

Fixes: e2c5e51fe1
2020-08-28 13:13:41 +03:00
Ben V. Brown
11f3eadfc9 Merge pull request #655 from paulfertser/temp-rfc-patches
RFC patches
2020-08-27 11:06:03 +10:00
Paul Fertser
b331032f30 Makefile: remove duplicated code generation options from LINKER_FLAGS
LINKER_FLAGS already includes CPUFLAGS via CXXFLAGS (and that's the
right way to have the correct options defined at a single place).
2020-08-26 15:07:28 +03:00
Paul Fertser
25aee6b661 Move I2CSemaphore creation outside postRToSInit
The code assumes that whenever scheduler is running I2CSemaphore is
available. Initialising it in a task might lead to race conditions and
is also not happening at all if the task is disabled (for debugging or
due to lack of need for a particular usecase).

The race condition can't happen with the current code though, as GUI
task has lower priority than the MOV task, and they're the only tasks
that currently use I2C. However, this might change in the future with
the code refactoring or introduction of new features.
2020-08-26 15:07:13 +03:00
Paul Fertser
c1dd88ba53 Allow SWD debugging when built with swd_enable=1 2020-08-26 11:54:29 +03:00
Paul Fertser
780f1f35ca Make flash and bootloader sizes configurable
This patch makes allocating special pages automatic and flexible,
allowing flash size and application start offset specification with
linker command line arguments. It should allow easier porting to
different targets and experimentation without adding code complexity.

Many original STM32F103x8 chips have fully functional 128 kiB flash and
so this additional space might come useful for experimentation,
additional optional features etc. Tested on v2.51A board, including
writing and verifying 128 kiB of random data.

Make variables are added to control that, so to build for the full
undocumented flash size and dapboot configured to start the app from 8
kiB offset one can run:

make flash_size=128k bootldr_size=0x2000
2020-08-26 11:53:47 +03:00
Paul Fertser
76099406ef Update FreeRTOS port-specific files to V10.3.1
This updates Cortex-M3 port files to version found in
V10.3.1-kernel-only tag of FreeRTOS-Kernel.

The new upstream release includes memory barriers which are essential
for use with modern optimising compilers. Without those firmware
certainly breaks with -O3 -flto and might be also broken with other
optimisation configurations.

Fixes: d59ec10c4e ("Update FreeRTOS to v10.3.1")
2020-08-26 11:52:05 +03:00
Ben V. Brown
e66fe461d2 Merge pull request #680 from dimitroffs/better-bg-translate
Better Bulgarian language translations
2020-08-20 07:53:18 +10:00
Dimitar Dimitrov
5d358feee9 Small changes after detailed view on a display 2020-08-19 18:18:58 +03:00
Ben V. Brown
09ff363ae5 Update README.md 2020-08-19 15:09:55 +10:00
Dimitar Dimitrov
e92a81c229 Better Bulgarian language translations 2020-08-17 16:42:27 +03:00
Ben V. Brown
138000f4a5 Merge pull request #672 from Ralim/supporting-FUSB302
Adding support for the TS80P using FUSB302 for USB-PD
2020-08-15 17:10:35 +10:00
Ben V. Brown
8faeb4e587 More accurate TS80P peak 12V current draw 2020-08-15 16:41:28 +10:00
Ben V. Brown
b370fcfa6f Fix warnings 2020-08-02 16:36:52 +10:00
Ben V. Brown
e4aab8aa91 Update pd.h 2020-08-02 16:27:34 +10:00
Ben V. Brown
c066ec8ae5 Setup delay not required anymore 2020-08-02 16:18:50 +10:00
Ben V. Brown
026e5cc9c5 NULL pointer checks for race 2020-08-02 16:18:43 +10:00
Ben V. Brown
666c250630 Setup to basically always pick 5V 2020-08-02 16:18:32 +10:00
Ben V. Brown
d73ad0d11c No need to listen to SOP' SOP" now 2020-08-02 16:18:17 +10:00
Ben V. Brown
0d03650726 Correct timings 2020-08-02 16:17:51 +10:00
Ben V. Brown
d47c28b760 Use mutex for priority inversion prevention 2020-08-02 16:17:41 +10:00
Ben V. Brown
e2c5e51fe1 Refactor to 1khz RToS 2020-08-01 21:16:23 +10:00
Ben V. Brown
9391158399 Re enable accel, fix accel flags & cleanup qc 2020-07-29 22:53:08 +10:00
Ben V. Brown
a39185315d Allow query PD for status and remove more cruft from PPS 2020-07-29 22:52:36 +10:00
Ben V. Brown
a59d008d07 Hold off QC until PD is done 2020-07-29 22:52:20 +10:00
Ben V. Brown
d68eb95f50 Cleanup more unrequired logic 2020-07-28 22:27:14 +10:00
Ben V. Brown
b6ee4207dd Dont need to soft reset if timing gives SOP' without SOP following
Easier to wait again and let timeout handle reset
2020-07-28 21:56:50 +10:00
Ben V. Brown
be57c4f58a Update BSP_PD.c 2020-07-28 21:43:42 +10:00
Ben V. Brown
7b41e2fcca Lower min spec to ~27W for 12v neg 2020-07-28 21:28:27 +10:00
Ben V. Brown
1e19fc80f4 Add ts80p to auto build 2020-07-28 21:26:26 +10:00
Ben V. Brown
add65ead9c Drop timer support as not used 2020-07-28 21:26:05 +10:00
Ben V. Brown
0b2311e001 Update config and clean up debugging calls 2020-07-28 21:20:36 +10:00
Ben V. Brown
8f395e2294 Update protocol_tx.cpp 2020-07-28 20:28:36 +10:00
Ben V. Brown
9832b97248 Header updates to match 2020-07-28 20:10:34 +10:00
Ben V. Brown
d35b2bf115 Update protocol_rx.cpp 2020-07-28 20:05:58 +10:00
Ben V. Brown
dd340d3a2b Port from test env cleanups 2020-07-28 20:05:47 +10:00
Ben V. Brown
8eacf50a5b mask stacked reset if another message recieved at the same time 2020-07-28 20:02:32 +10:00
Ben V. Brown
c9a8794fb9 Policy handle already pending message 2020-07-28 20:01:56 +10:00
Ben V. Brown
23ce11a68f Listen for SOP packets too to keep in sync (discard at software layer) 2020-07-28 19:59:28 +10:00
Ben V. Brown
e6d1249c91 Cleanup model selection 2020-07-25 22:28:38 +10:00
Ben V. Brown
f36e78f664 . 2020-07-23 22:49:05 +10:00
Ben V. Brown
ff65e6437b Shrink flash usage _just_ enough 2020-07-23 22:45:00 +10:00
Ben V. Brown
85decdc15b Merge branch 'master' into supporting-FUSB302 2020-07-23 20:26:56 +10:00
Ben V. Brown
b40a21470b Update fusbpd.cpp 2020-07-22 23:09:46 +10:00
Ben V. Brown
9b0a071e9a Cleaning up a bit for ease of integration 2020-07-22 23:06:59 +10:00
Ben V. Brown
1f6dfe5da5 MVP 2020-07-22 22:59:20 +10:00
Ben V. Brown
4441a5ca93 Handle NTC in TS80P 2020-07-22 22:54:55 +10:00
Ben V. Brown
1cebcdc42b Works on SRC only units.. mostly 2020-07-22 22:39:35 +10:00
Ben V. Brown
6097216b24 Port unreliable but starter PD setup 2020-07-22 22:39:20 +10:00
Ben V. Brown
164c402d1c Update I2CBB.cpp 2020-07-22 22:33:18 +10:00
Ben V. Brown
db517a13e8 Merge pull request #670 from pfeerick/patch-1
Upgrading.md - Use file explorer, not alternatives when upgrading on Windows
2020-07-22 22:19:34 +10:00
Peter
237a1b2dea Use native file explorer, not alternatives
Add mention of not using alternative file managers / copy handlers, similar to wiki mention.

Resolves #544
2020-07-22 20:37:11 +10:00
Ben V. Brown
b6c61cfb52 Still testing 2020-07-21 13:39:50 +10:00
Ben V. Brown
1cc4153315 Merge pull request #665 from Swyter/master
Update the Spanish translation to cover the recent UI changes
2020-07-06 21:44:24 +10:00
Swyter
96d368b91a Last tweaks to the Castilian Spanish translation. The power pulse option acts a bit weird, so shorten the string a big. Happy with the rest. 2020-07-05 14:27:00 +02:00
Swyter
93ef2ea2f1 Minor tweaks to the Castilian Spanish translation, to improve the layout, the explanations and to adapt better to the tight space. 2020-07-05 14:00:07 +02:00
Swyter
a48a5ddf84 Update the Spanish translation to cover the recent UI changes. 2020-07-05 12:31:46 +02:00
Ben V. Brown
a81511ceb9 Merge pull request #659 from paulfertser/fix-tempchange-menu
Fix "Temp change short/long" menu display
2020-06-21 10:25:08 +10:00
Ben V. Brown
6cf245f33e Merge pull request #660 from paulfertser/fix-thumb-position
Fix scrollbar thumb position for long menus
2020-06-21 10:23:41 +10:00
Paul Fertser
099d6b8aee Fix scrollbar thumb position for long menus
Advanced settings menu has 9 entries so the thumb ends up being one
pixel high and on the 9th menu it ends up being closer to the middle of
the screen rather than the end. This patch fixes it.
2020-06-21 00:37:15 +03:00
Paul Fertser
021b8e2fc8 Fix "Temp change short/long" menu display
The values are only two digits so do not overwrite the end of the menu
item string.

Fixes: #658.
2020-06-20 23:41:44 +03:00
Ben V. Brown
c70689df7d Hook up IRQ 2020-06-17 18:22:43 +10:00
Ben V. Brown
43b7947645 Update fusbpd.cpp 2020-06-17 18:15:27 +10:00
Ben V. Brown
12e8d2a93d Update hard_reset.cpp 2020-06-17 18:15:22 +10:00
Ben V. Brown
c55b91af6a static state 2020-06-17 18:15:16 +10:00
Ben V. Brown
6d23617670 IRQ int 2020-06-17 18:14:17 +10:00
Ben V. Brown
4c2fb11d32 Filter returned WFE 2020-06-16 21:25:28 +10:00
Ben V. Brown
2fd06887e8 Better messages flowing 2020-06-16 20:21:26 +10:00
Ben V. Brown
54a8aa7ac6 I2C protection 2020-06-16 20:19:06 +10:00
Ben V. Brown
968e22c7dc Add blank flash hex 2020-06-15 18:56:11 +10:00
Ben V. Brown
9ea92a3c17 Disable i2c slave code (shaves off a few hundred bytes) 2020-06-14 21:12:41 +10:00
Ben V. Brown
61f991e423 Fix watchdog timeouts && get unit to boot 2020-06-14 21:12:25 +10:00
Ben V. Brown
f196c5f1c9 Moving PD framework + big thread cleanup 2020-06-14 16:32:11 +10:00
Ben V. Brown
60abcb0d8b Merge pull request #648 from federck/patch-24
IT_translation update
2020-06-13 23:11:17 +10:00
Ben V. Brown
051417d515 Merge pull request #650 from paulfertser/ts100-swd-over-usb
New TS100 v2.51A version allows SWD over USB pins
2020-06-13 23:10:59 +10:00
Ben V. Brown
2c0b14edd4 Culling until fits in code
Does _not_ negotiate correctly :(
2020-06-12 22:13:40 +10:00
Ben V. Brown
34ae57ee58 Bitbang I2C setup + detect test 2020-06-12 21:10:03 +10:00
Ben V. Brown
aa4485d1d9 Merge pull request #652 from radjah/patch-1
Typos and commas
2020-06-12 07:27:16 +10:00
Ben V. Brown
479b9fc670 Merge pull request #651 from pelkat/dev_tpe
Translated remaining CS (czech) strings
2020-06-12 07:26:41 +10:00
Radjah
5444c3f8de Typos and commas
Corrected errors in the text
2020-06-11 18:16:14 +03:00
Ben V. Brown
450ce17935 Import existing FUSB302 library 2020-06-11 23:30:06 +10:00
Tomas Pelka
753310c212 Translated remaining CS (czech) strings 2020-06-11 14:08:21 +02:00
Ben V. Brown
954770373c Starting the roughout 2020-06-11 18:50:36 +10:00
Paul Fertser
d2b05570fc New TS100 v2.51A version allows SWD over USB pins 2020-06-09 23:36:19 +03:00
federck
b3d16df69a Update translation_it.json 2020-06-07 16:40:53 +03:00
federck
30d8490128 Update translation_it.json 2020-06-07 14:11:58 +03:00
federck
05c5e04bed IT_translation update 2020-06-07 13:32:57 +03:00
Ben V. Brown
18a2c0a9ec Merge pull request #644 from Ralim/docs
Updating some of the markdown docs
2020-06-03 12:01:30 +10:00
Ben V. Brown
88caa3f3c7 Merge pull request #645 from Realetive/patch-1
Fix mistakes
2020-06-03 12:01:12 +10:00
Ben V. Brown
316de7cb1e Merge pull request #638 from playday3008/patch-1
Update translation_uk.json
2020-06-03 12:01:01 +10:00
Ben V. Brown
3b4852f8fb Merge pull request #646 from KITT3000/patch-1
Update PL translation
2020-06-03 12:00:23 +10:00
Ziuta
b7ad1ae0cd Update translation_pl.json 2020-06-02 17:24:41 +02:00
Ziuta
9491262e87 Update PL translation 2020-06-02 17:22:41 +02:00
Realetive
9c86cd228c Fix mistakes 2020-06-02 17:43:07 +03:00
PlayDay
dd5d2c955d Merge branch 'master' into patch-1 2020-06-02 15:57:25 +02:00
Ben V. Brown
f28ba93f0e Update README.md 2020-06-02 22:36:43 +10:00
Ben V. Brown
e6129c3456 Update README.md 2020-06-02 22:32:47 +10:00
Ben V. Brown
b3507218ad Update menu.md 2020-06-02 22:32:44 +10:00
Ben V. Brown
7518a2fe7d Create upgrading.md 2020-06-02 22:32:42 +10:00
Ben V. Brown
76f2278516 Merge pull request #643 from Ralim/update-freertos
Update FreeRTOS to v10.3.1
2020-06-02 18:50:13 +10:00
Ben V. Brown
d59ec10c4e Update FreeRTOS to v10.3.1 2020-06-02 18:20:16 +10:00
Ben V. Brown
64d5e8b1af Fix mixtake in I2C probe check 2020-05-30 18:35:15 +10:00
Ben V. Brown
441ac7f83a Move IRQ's for easier tracing 2020-05-30 18:34:49 +10:00
PlayDay
71a09c0014 Update translation_uk.json 2020-05-30 08:07:36 +02:00
PlayDay
4dc1a19230 Update translation_uk.json 2020-05-30 07:46:39 +02:00
PlayDay
76881e6f50 Update translation_uk.json 2020-05-30 07:42:10 +02:00
PlayDay
93c87fd91d Update translation_uk.json
Forgot  ","
2020-05-30 07:29:21 +02:00
PlayDay
abbcd05117 Update translation_uk.json
Don't merge now
2020-05-30 07:24:09 +02:00
140 changed files with 16215 additions and 7541 deletions

View File

@@ -3,22 +3,75 @@ name: C/C++ CI
on: [pull_request, push]
jobs:
build:
build_TS80:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: chmod
run: chmod +x build.sh
- name: translation
run: |
cd Translation\ Editor
python3 make_translation.py
- name: make
run: ./build.sh
- name: Archive production artifacts
uses: actions/upload-artifact@v1
run: chmod +x setup.sh && chmod +x workspace/TS100/build.sh
- name: setup
run: ./setup.sh
- name: build TS80
run: cd workspace/TS100 && ./build.sh -m TS80
- name: Archive TS80 artifacts
uses: actions/upload-artifact@v2
with:
name: compiled
path: ci/artefacts
name: TS80
path: |
workspace/TS100/Hexfile/TS80_*.hex
workspace/TS100/Hexfile/TS80_*.bin
if-no-files-found: error
build_TS80P:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: chmod
run: chmod +x setup.sh && chmod +x workspace/TS100/build.sh
- name: setup
run: ./setup.sh
- name: build TS80P
run: cd workspace/TS100 && ./build.sh -m TS80P
- name: Archive TS80P artifacts
uses: actions/upload-artifact@v2
with:
name: TS80P
path: |
workspace/TS100/Hexfile/TS80P_*.hex
workspace/TS100/Hexfile/TS80P_*.bin
if-no-files-found: error
build_TS100:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: chmod
run: chmod +x setup.sh && chmod +x workspace/TS100/build.sh
- name: setup
run: ./setup.sh
- name: build TS100
run: cd workspace/TS100 && ./build.sh -m TS100
- name: Archive TS100 artifacts
uses: actions/upload-artifact@v2
with:
name: TS100
path: |
workspace/TS100/Hexfile/TS100_*.hex
workspace/TS100/Hexfile/TS100_*.bin
if-no-files-found: error

1
.gitignore vendored
View File

@@ -190,3 +190,4 @@ fabric.properties
.idea/httpRequests
CoreCompileInputs.cache
.vscode/settings.json

File diff suppressed because it is too large Load Diff

View File

@@ -6,10 +6,10 @@ WORKDIR /build
# Install any needed packages specified in requirements.txt
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
make \
bzip2 \
git \
python3 \
wget && \
apt-get clean

View File

@@ -1,5 +1,64 @@
# Version Changes
V2.00
## V2.11
* First TS80P support
* Added in a USB-PD driver stack for the FUSB302
* Fixed some graphical glitches
## V2.10
* GUI polish (animations and scroll bars)
* Power pulse to keep power supplies alive
* Adjustable tip response gain
## V2.09
* Adjustable steps in temperature adjustment
* Git hash now in build string
* Adjustable language to set if US units are available or not
* Some minor QC3 improvements
## V2.08
* Fixes auto start in sleep mode
* Power limiters
## V2.07
* QC fixes
* Cosmetic fixes for leading 0's
## V2.06
* Warning on settings reset
* Temp temp re-write
* Display calibration offset
* Hide some leading 0's
* Menu timeouts
## V2.05
* Language updates
## V2.04
* GUI updates
## V2.03
* Support for new accelerometers
## V2.02
* Adds small font
## V2.01
* Newer settings menu
## V2.00
* Complete re-write of the low layer system to use the STM32 HAL for easier development
* This allowed easier setup for the new ADC auto measuring system
@@ -10,80 +69,80 @@ V2.00
* Added smaller font for said screen views
V1.17
## V1.17
* Added blinking cooldown display
* Allowed smaller sleep timeout values
* New font!
* Automatic startup option
V1.16
## V1.16
* Added automatic rotation support
* Added power display graph
V1.15
## V1.15
* Added support for a custom bootup logo to be programmed via the DFU bootloader
V1.14
## V1.14
* Changed input voltage cutoff to be based on cell count rather than voltage
V1.13
## V1.13
* Swapped buttons for menu to prevent accidentally changing first menu item
* Added auto key repeat
V1.12
## V1.12
* Increases sensitivity options to be 1*9 with 0 off state
* Fixes issue where going from COOL *> soldering can leave screen off
V1.11
## V1.11
* Boost mode
* Change sensitivity options to be 1*8
V1.10
## V1.10
* Adds help text to settings
* Improves settings for the display update rate
V1.09
## V1.09
* Adds display modes, for slowing down or simplifying the display
V1.08
## V1.08
* Fix settings menu not showing flip display
V1.07
## V1.07
* Adds shutdown time to automatically shutdown the iron after inactivity
V1.06
## V1.06
* Changes H and C when the iron is heating to the minidso chevron like images
V1.05
## V1.05
* Adds ability to calibrate the input voltage measurement
V1.04
## V1.04
* Increased accuracy of the temperature control
* Improved PID response slightly
* Allows temperature offset calibration
* Nicer idle screen
V1.03
## V1.03
* Improved Button handling
* Ability to set motion sensitivity
* DC voltmeter page shows input voltage
V1.02
## V1.02
* Adds hold both buttons on IDLE to access the therometer mode
* Changes the exit soldering mode to be holding both buttons (Like original firmware)

View File

@@ -1,5 +1,6 @@
# Menu System
In this firmware for these soldering irons, all settings are adjustable on the device itself. This means you do **not** require a computer to change any settings.
## Soldering mode
@@ -24,7 +25,6 @@ Scrolling through the submenu will return you back to its entry location after y
Due to the tolerance on the resistors used for the input voltage divider, some irons can be up to 0.6V out on the voltage measurement.
Please calibrate your iron if you have any issues with the cutoff voltage.
Note that cutoff messages can also be triggered by using a power supply that is too weak and fails under the load of the iron.
This is more critical than before with the new cell count based cutout voltage.
To calibrate your iron:

View File

@@ -0,0 +1,72 @@
# Upgrading your iron
## Miniware irons (TS100, TS80, TS80P)
This is completely safe, but if it goes wrong just put the .hex file from the official website onto the unit and you're back to the old firmware. Downloads for the hex files to flash are available on the [releases page.](https://github.com/Ralim/ts100/releases) The file you want is called *(MODEL)_EN.hex* unless you want the translations, they are (MODEL)_*language short name*.hex. Where (MODEL) is either TS100 or TS80.
Officially the bootloader on the iron only works under Windows (use the built-in File Explorer, as alternative file managers or copy handlers like Teracopy will fail). However, users have reported that it does work under Mac, and can be made to work under Linux *sometimes*. Details over on the [wiki page](https://github.com/Ralim/ts100/wiki/Upgrading-Firmware).
1. Hold the button closest to the tip, and plug in the USB to the computer.
2. The unit will appear as a USB drive.
3. Drag the .hex file onto the USB drive.
4. The unit will disconnect and reconnect.
5. The filename will have changed to end in .RDY or .ERR
6. If it ends with .RDY you're done! Otherwise, something went wrong.
7. If it didn't work the first time, try copying the file again without disconnecting the iron, often it will work on the second shot.
8. Disconnect the USB and power up the iron. You're good to go.
For the more adventurous out there, you can also load this firmware onto the device using an SWD programmer.
On the bottom of the MCU riser PCB, there are 4 pads for programming. On v2.51A PCB revision `USB_D+` is shorted to `SWDIO` and `USB_D-` is shorted to `SWCLK` so debugging works without disassembly (attach while staying in the bootloader). Installing [dapboot from eDesignOSS](https://github.com/eDesignOSS/dapboot) (`make TARGET=TS100 -C src`) is recommended as it allows reliable flashing of binary files with [dfu-util](http://dfu-util.sourceforge.net/).
There is a complete device flash backup included in this repository. (Note this includes the bootloader, so will need an SWD programmer to load onto the unit).
For the TS80 the SWD pins are used for the QC negotiation, so you can actually connect to the SWD power via the USB connector.
### FAQ
#### The file is showing up with the extension `.ERR`
This can occur duing the programming process if any of the checks in the bootloader fail. This is often triggered by anti-virus software or using a non-windows host OS.
First, try just copying the file a second time.
1. Attach the iron in DFU mode
2. Copy the hex file to the device
3. The device disconnects and connects with the `.ERR` file
4. Copy the same hex file again **DO NOT TRY AND DELETE THE OLD ONE**
5. The device will disconnect and reconnect again
6. The device _should_ now have the `.RDY` file
7. Your done.
If this fails, if you are on Mac or Linux reading the wiki page about programming can help. There is also a very long issue thread going through all of the different attempts around this too.
If you are on windows, its often to try another computer (friends, work, partners etc).
#### Device randomly disconnects or does not show up in DFU mode
First, check the USB cable your using has the data pins; test it on another device. There are a surprisingly large number of usb-micro cables that are power _only_.
Secondly, try other USB ports. Often different USB controllers will interact with the units differently due to design quirks in the miniware design.
## Setting a custom bootup image
This firmware uses a different method of updating the bootup image.
This removes the need for emulating a USB drive on the iron just to allow for a bootup image to be setup.
There are further instructions on the [wiki](https://github.com/Ralim/ts100/wiki/Logo-Editor).
Instructions are kept on the wiki so that users can update the information if they find extra helpful information.
## Alternative bootloader
If you are an advanced user, and you have used `usb-dfu` tools before, or you would like to learn; there is an alternative bootloader for these irons.
This will **NOT** show up as a USB storage drive, but instead show up using a standard DFU protocol device. You can then use dfu tools or GUI's to upgrade the iron using the `.bin` files that are posted to the releases page.
To change to dapboot based alternative bootloader, you need to flash the hex file from [here](https://github.com/eDesignOSS/ts100-bl-flasher/releases).
`ts100-stockbl.hex` will reflash the stock bootloader, `ts100-dapboot.hex` will flash the new dapboot based usb bootloader.
Note that this is only reccomended for users who know what they doing. If you dont not understand how this works; please dont flash this.

View File

@@ -1,31 +1,21 @@
Please edit this template and fill out all the information you can (where relevant). Failure to provide essential information can delay the response you receive.
_This is a [Bug/Feature Request/Question/Complaint]_
* **I'm submitting a ...**
- [ ] Bug report
- [ ] Feature request
- [ ] Translation
* **Do you want to request a *feature* or report a *bug*?**
* **I have**
- [ ] Searched previous issues
- [ ] This is in _this_ firmware, not vendor "offical" firmware
- [ ] This is not a bug in the vendor bootloader (aka DFU)
- [ ] I have checked this is not already covered in the docs in `/Documentation`
* **What is the current behavior?**
* **What is the expected behavior?**
***Steps to reproduce the bug:***
* **If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem**
***Steps to reproduce:***
1.
2.
3.
***Video of problem if hard to reproduce***
- Turn on...
- Hold....
* **What is the motivation / use case for changing the behavior?**
@@ -33,13 +23,9 @@ Please edit this template and fill out all the information you can (where releva
* **What are you running:**
On the idle screen, you can hold the settings button and it will show you the firmware version.
On the idle screen, you can hold the settings button and it will show you the firmware & PCB version.
If using a USB-C supply please note model number
- Firmware Version: 2.x
- Firmware Version: 2.x?
- PCB Version: (1/2)
- Power Supply (Voltage and Current Rating) :
* **Other information**
If submitting graphics to go on the iron, please use BMP or PNG files over JPG.
- Power Supply (Voltage and Current Rating) :

View File

@@ -2,9 +2,8 @@
Please try and fill out this template where possible, not all fields are required and can be removed.
* **Please check if the PR fulfills these requirements**
- [] The commit message makes sense
- [] The changes have been tested locally
- [] Are there any breaking changes
- [] There are no breaking changes
* **What kind of change does this PR introduce?**
(Bug fix, feature, docs update, ...)
@@ -14,14 +13,6 @@ Please try and fill out this template where possible, not all fields are require
* **What is the current behavior?**
(You can also link to an open issue here)
* **What is the new behavior (if this is a feature change)?**
* **Does this PR introduce a breaking change?**
(What changes might users need to make in their application due to this PR?)
* **Other information**:

View File

@@ -1,72 +1,41 @@
[![Codeship Status for ts100](https://app.codeship.com/projects/c77dbfe0-0764-0138-9520-3eb35bdb2b2c/status?branch=master)](https://app.codeship.com/projects/379118)
![C/C++ CI](https://github.com/Ralim/ts100/workflows/C/C++%20CI/badge.svg)
# TS100 & TS80 Firmware
# Flexible Soldering iron control Firmware
*Please Note, this repo will likely be renaming soon to unire - See issue #639. Old links willcontinue to work, and should redirect. So dont panic :) This is just to better account for the newer soldeing irons being added.*
This firmware is a fresh start for these soldering irons. Designed from the ground up as fully featured control software that leaves nothing to be desired.
It originally started back at the end of 2016 and has since seen vast improvements, especially some very smart work by community members.
Originally concieved as an alternative firmware for the TS100, this firmware has evolved into a complex soldering iron control firmware.
The firmware supports everything you would expect in the soldering iron and has the same features as the stock firmware with some nice extras packed in.
There is a comprehensive menu system in the iron that allows for adjustment of all the settings on the unit, and support for various languages is added by the community.
The firmware implements all of the standard features of a "smart" soldering iron, with lots of little extras and tweaks.
I highly reccomend reading the installation guide fully when installing on your iron.
On the TS100 there are settings to allow you to specify a cutoff voltage for different lithium-ion battery packs to protect your power source.
For the TS80 these are removed and replaced with the selection of 18W or 24W depending on what your QC power bank can support.
Otherwise, both systems work very similar and should support all the features.
For soldering irons that are designed to be powered by "smart" power sources (QC and PD), the firmware supports settings around the negotiated power and voltage.
For soldering irons that are designed to be powered by batteries (TS100), settings for a cutoff voltage for battery protection are supported.
There are 25 languages currently supported as of present. When downloading the firmware for your soldering iron take node of the language code in the file name.
This project is considered feature complete for use as a soldering iron, *so please suggest any feature improvements you would like!*
*This firmware does **NOT** support the USB port while running for changing settings. This is done through the onscreen menu only. Logos are edited using the tool or python script and uploaded in DFU mode.*
## Core Features
## Key Features
* PID iron temperature control
* PID style iron temperature control
* Automatic sleep with selectable sensitivity
* Motion wake support
* Settings menu on the unit
* All settings exposed in intuitive menu
* (TS100) Set a voltage lower limit for Lithium batteries so you don't kill your battery pack
* (TS80 ) Set 18W or 24W settings for your power bank
* All settings saved to flash when you exit the menu
* (TS80) Set 18W or 24W settings for your power bank
* Improved readability Fonts
* Use hardware features to improve reliability
* Can disable movement detection if desired
* Full tip profile calibration
* Boost mode lets you temporarily change the temperature when soldering (ie raise the temperature for short periods of time)
* Boost mode lets you temporarily change the temperature when soldering (i.e. raise the temperature for short periods of time)
* (TS100) Battery charge level indicator if power source set to a lipo cell count
* (TS80) Power bank operating voltage is displayed
* Custom boot up logo support
* [Custom boot up logo support](Documentation/upgrading.md)
* Automatic LCD rotation based on the orientation
* Supports both the version 1 and version 2 hardware (different accelerometers)
# Upgrading your iron
This is completely safe, but if it goes wrong just put the .hex file from the official website onto the unit and you're back to the old firmware. Downloads for the hex files to flash are available on the [releases page.](https://github.com/Ralim/ts100/releases) The file you want is called *(MODEL)_EN.hex* unless you want the translations, they are (MODEL)_*language short name*.hex. Where (MODEL) is either TS100 or TS80.
Officially the bootloader on the iron only works under Windows. However, users have reported that it does work under Mac, and can be made to work under Linux *sometimes*. Details over on the [wiki page](https://github.com/Ralim/ts100/wiki/Upgrading-Firmware).
```
1. Hold the button closest to the tip, and plug in the USB to the computer.
2. The unit will appear as a USB drive.
3. Drag the .hex file onto the USB drive.
4. The unit will disconnect and reconnect.
5. The filename will have changed to end in .RDY or .ERR
6. If it ends with .RDY you're done! Otherwise, something went wrong.
7. If it didn't work the first time, try copying the file again without disconnecting the iron, often it will work on the second shot.
8. Disconnect the USB and power up the iron. You're good to go.
```
For the more adventurous out there, you can also load this firmware onto the device using an SWD programmer.
On the bottom of the MCU riser PCB, there are 4 pads for programming.
There is a complete device flash backup included in this repository. (Note this includes the bootloader, so will need an SWD programmer to load onto the unit).
For the TS80 the SWD pins are used for the QC negotiation, so you can actually connect to the SWD power via the USB connector.
## Setting a custom bootup image
This firmware uses a different method of updating the bootup image.
This removes the need for emulating a USB drive on the iron just to allow for a bootup image to be setup.
There are further instructions on the [wiki](https://github.com/Ralim/ts100/wiki/Logo-Editor).
Instructions are kept on the wiki so that users can update the information if they find extra helpful information.
# Menu System
This new firmware uses a new menu system to allow access to the settings on the device.
@@ -77,32 +46,34 @@ When on the main screen, the unit shows prompts for the two most common operatio
* Holding the button near the tip will enter soldering temperature adjust mode (This is the same as the one in the soldering menu, just to let you edit before heating up)
* Holding the button near the USB end will show the firmware version details
More details are over in the [Menu information.](menu.md)
Detailed operation details are over in the [Menu information.](Documentation/menu.md)
## Thanks
If you love this firmware and want to continue my caffeine addiction, you can do so here (or email me for other options) : https://paypal.me/RalimTek
If you love this firmware and want to continue my caffeine addiction, you can do so [here](https://paypal.me/RalimTek) (or email me for other options).
I also want to give a shout out to all of the [Fantastic Contributors](https://github.com/Ralim/ts100/graphs/contributors).
Especially to the following users, who have helped in various ways that are massively appreciated:
* [dhiltonp](https://github.com/dhiltonp)
* [Dhiltonp](https://github.com/dhiltonp)
* [Mrkvozrout](https://github.com/Mrkvozrout)
* [jonnieZG](https://github.com/jonnieZG)
* [federck](https://github.com/federck)
* [jvitkauskas](https://github.com/jvitkauskas)
* [doegox](https://github.com/doegox)
* [perillamint](https://github.com/perillamint)
* [JonnieZG](https://github.com/jonnieZG)
* [Federck](https://github.com/federck)
* [Jvitkauskas](https://github.com/jvitkauskas)
* [Doegox](https://github.com/doegox)
* [Perillamint](https://github.com/perillamint)
* [GeminiServer](https://github.com/GeminiServer)
* [Patrick Horlebein](https://github.com/PixelPirate)
* [Firebie](https://github.com/Firebie)
* [Agatti](https://github.com/agatti)
* [Discip](https://github.com/discip)
* [Paul Fertser](https://github.com/paulfertser)
## Licence
The code in this repository that is based on the STM tools is under a BSD-like licence.
The code created by the community is GNU GPLv3. Unless noted elsewhere.
The FreeRToS is under its own licence.
Other components such as FreeRTOS have their own licence.
## Commercial Use
This software is provided as-is, so I cannot provide any commercial support for the firmware. However, you are more than welcome to distribute links to the firmware, or provide irons with this software on them.
Please do not re-host the files, but rather link to this page, so that there are no old versions of the firmware scattered around. If this firmware does make you money, it would be nice to receive a donation, however, there is no enforcement.
Please do not re-host the files, but rather link to this page, so that there are no old versions of the firmware scattered around.

View File

@@ -1,353 +1,329 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TS100 Translation Editor</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="translations_commons.js"></script>
<script src="translations_def.js"></script>
<script>
var app;
var defMap = {};
function save(){
saveJSON(app.current, "translation_"+app.current.languageCode.toLowerCase()+".json");
}
function view(){
showJSON(app.current, "translation_"+app.current.languageCode.toLowerCase()+".json");
}
function fileChanged(e) {
var target = e;
var id = target.id;
var file = target.files[0];
if (!file) {
return;
}
var fr = new FileReader();
fr.onload = function(e) {
try {
var json = JSON.parse(e.target.result);
} catch (ex) {
console.log(ex);
alert("Invalid JSON file: " + file.name);
return;
}
if (id == "referent-lang-file") {
if (checkTranslationFile(file.name)) {
app.referent = json;
app.meta.referentLoaded = true;
}
} else if (id == "current-lang-file") {
if (checkTranslationFile(file.name)) {
app.current = json;
if (!app.current.cyrillicGlyphs){
app.current.cyrillicGlyphs = false;
}
app.meta.currentLoaded = true;
}
}
synchronizeData();
}
fr.readAsText(file);
}
function synchronizeData() {
app.obsolete = {};
copyMissing(app.def.messages, app.referent.messages, app.current.messages);
copyMissing(app.def.characters, app.referent.characters, app.current.characters);
copyMissing(app.def.menuGroups, app.referent.menuGroups, app.current.menuGroups);
copyMissing(app.def.menuOptions, app.referent.menuOptions, app.current.menuOptions);
}
/**
* Copy all missing properties from referent to current
* for each entry in definition
*/
function copyMissing(defList, referentMap, currentMap) {
if (!isDefined(defList) || !isDefined(referentMap) || !isDefined(currentMap)) {
return;
}
var len = defList.length;
for (var i = 0; i < len; i++) {
var id = defList[i].id;
if (!isDefined(referentMap[id])) {
referentMap[id] = '';
}
if (!isDefined(currentMap[id])) {
currentMap[id] = referentMap[id];
}
}
processObsolete(defList, currentMap);
}
// Passes through all entries from the given map.
// If a corresponding entry is not found in the defList, it is removed from the map, and added into the obsolete map.
function processObsolete(defList, map) {
// Index list to map for faster search
var defMap = copyArrayToMap(defList);
Object.keys(map).forEach(function(key) {
if (!isDefined(defMap[key])) {
app.obsolete[key] = { id : key, value : map[key]};
delete map[key];
}
});
}
function length(obj, mode) {
if (!isDefined(mode) || mode == 0) {
// return direct length
return obj.length;
} else if (mode == 1) {
// return length of text property
return obj.text.length;
} else if (mode == 2) {
// return the longest length in text2 array
return Math.max(isDefinedNN(obj.text2[0]) ? obj.text2[0].length : 0, isDefinedNN(obj.text2[1]) ? obj.text2[1].length : 0);
}
}
function getAttribute(obj, attribute, isDouble) {
var d = isDouble ? "2" : "";
var v = obj[attribute+d];
if (isDefined(v))
return v;
return obj[attribute];
}
function loaded() {
app = new Vue({
el : '#app',
data : {
meta : {
referentLoaded : false,
currentLoaded : false,
},
def : {
},
referent : {
messages : {}
},
current : {
loaded: false,
},
obsolete : {},
menuDouble : false
},
methods : {
validateInput: function(valMap, id, mode) {
var d = defMap[id];
var vLen = 0;
if (!isDefined(mode))
mode = 0;
try {
// Sum for complex length
for (var i = 0; i < d.lenSum.fields.length; i++) {
vLen += length(valMap[d.lenSum.fields[i]], mode);
}
d = d.lenSum;
} catch (e) {
// Single field length
vLen = length(valMap[id], mode);
}
var maxLen = getAttribute(d, 'maxLen', mode == 2);
var minLen = getAttribute(d, 'minLen', mode == 2);
var len = getAttribute(d, 'len', mode == 2);
if (isNumber(maxLen) && vLen > maxLen
|| isNumber(minLen) && vLen < minLen
|| isNumber(len) && vLen != len
) {
return "invalid";
}
},
constraintString: function(e, d) {
var str = "";
var delim = "";
var v;
if (!isDefined(d) || d == false) {
d = "";
} else {
d = "2";
}
if (isDefinedNN(e.lenSum)) {
str = "len("+(e.lenSum.fields+"").replace(/,/g," + ")+") -> ";
e = e.lenSum;
}
v = getAttribute(e, 'len', d);
if (isNumber(v)) {
str += delim + "len=" + v;
delim = " and ";
}
v = getAttribute(e, 'minLen', d);
if (isNumber(v)) {
str += delim + "len>=" + v;
delim = " and ";
}
v = getAttribute(e, 'maxLen', d);
if (isNumber(v)) {
str += delim + "len<=" + v;
delim = " and ";
}
return str;
}
}
});
app.def = def;
copyArrayToMap(app.def.messages, defMap);
copyArrayToMap(app.def.characters, defMap);
copyArrayToMap(app.def.menuGroups, defMap);
copyArrayToMap(app.def.menuOptions, defMap);
}
window.onload=loaded;
</script>
<link href="translations.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="app">
<h1>TS100 Translation Editor<span v-if="meta.currentLoaded"> - {{ current.languageLocalName }} [{{current.languageCode}}]</span></h1>
<table class="header data">
<tr>
<td class="label">Referent Language</td>
<td class="value">
<input type="file" id="referent-lang-file" onchange="fileChanged(this)" accept=".json">
<span class="selected" v-if="meta.referentLoaded">{{ referent.languageLocalName }} [{{referent.languageCode}}]</span>
</td>
</tr>
<tr v-if="meta.referentLoaded">
<td class="label">Current Language</td>
<td class="value">
<input type="file" id="current-lang-file" onchange="fileChanged(this)" accept=".json">
<span class="selected" v-if="meta.currentLoaded">{{ current.languageLocalName }} [{{current.languageCode}}]</span>
</td>
</tr>
<tr v-if="meta.currentLoaded">
<td class="label">Local Language Code</td>
<td class="value"><input type="text" v-model="current.languageCode" maxlength="8" v-on:change="current.languageCode=current.languageCode.toUpperCase()" class="short"></td>
</tr>
<tr v-if="meta.currentLoaded">
<td class="label">Local Language Name</td>
<td class="value"><input type="text" v-model="current.languageLocalName" class="short"></td>
</tr>
<tr v-if="meta.currentLoaded">
<td class="label">Font table to use</td>
<td class="value">
<select v-model="current.cyrillicGlyphs" v-on:change="current.cyrillicGlyphs = current.cyrillicGlyphs=='true'">
<option value="false">Latin Extended</option>
<option value="true">Cyrillic Glyphs</option>
</select>
</td>
</tr>
</table>
<div v-if="def.messages && referent.messages && current.messages">
<div class="footer">
<input type="button" value="Save" onclick="save()">
<input type="button" value="View" onclick="view()">
</div>
<div v-if="Object.keys(obsolete).length > 0">
<h2>Obsolete</h2>
<table class="data">
<tr v-for="entry in obsolete">
<td class="label"><div class="stringId">{{entry.id}}</div></td>
<td class="value"><div class="ref">{{entry.value}}</div></td>
</tr>
</table>
</div>
<h2>Messages and Strings</h2>
<table class="data">
<tr v-for="message in def.messages" v-bind:class="validateInput(current.messages, message.id)">
<td class="label"><div class="stringId">{{message.id}}</div></td>
<td class="value">
<div class="constraint">{{constraintString(message)}}</div>
<div class="ref">{{referent.messages[message.id]}}</div>
<div class="note" v-if="message.note">{{message.note}}</div>
<div class="tran"><input :id="'in_'+message.id" type="text" v-model="current.messages[message.id]" v-bind:class="{unchanged : current.messages[message.id] == referent.messages[message.id], empty : current.messages[message.id]==''}"></div>
</td>
</tr>
</table>
<h2>Characters</h2>
<table class="data">
<tr v-for="char in def.characters" v-bind:class="validateInput(current.characters, char.id)">
<td class="label"><div class="stringId">{{char.id}}</div></td>
<td class="value">
<div class="constraint">{{constraintString(char)}}</div>
<div class="ref">{{referent.characters[char.id]}}</div>
<div class="tran"><input type="text" v-model="current.characters[char.id]" v-bind:class="{unchanged : current.characters[char.id] == referent.characters[char.id], empty : current.characters[char.id].length != 1}"></div>
</td>
</tr>
</table>
<h2>Menu Groups</h2>
<table class="data">
<tr v-for="menu in def.menuGroups" v-bind:class="validateInput(current.menuGroups, menu.id, 2)">
<td class="label"><div class="stringId">{{menu.id}}</div></td>
<td class="value">
<div class="label">Menu Name</div>
<div class="constraint">{{constraintString(menu)}}</div>
<div class="ref">{{referent.menuGroups[menu.id].text2}}</div>
<div class="tran" v-bind:class="{unchanged : current.menuGroups[menu.id].text2[0] == referent.menuGroups[menu.id].text2[0] && current.menuGroups[menu.id].text2[1] == referent.menuGroups[menu.id].text2[1], empty : current.menuGroups[menu.id].text2[0] == '' || current.menuGroups[menu.id].text2[1] == ''}"><input type="text" v-model="current.menuGroups[menu.id].text2[0]"><input type="text" v-model="current.menuGroups[menu.id].text2[1]"></div>
<div class="label">Description</div>
<div class="ref">{{referent.menuGroups[menu.id].desc}}</div>
<div class="tran"><input type="text" v-model="current.menuGroups[menu.id].desc" v-bind:class="{unchanged : current.menuGroups[menu.id].desc == referent.menuGroups[menu.id].desc, empty : current.menuGroups[menu.id].desc == ''}"></div>
</td>
</tr>
</table>
<h2>Menu Options</h2>
<table class="data">
<tr>
<td class="label">Menu Type</td>
<td class="value">
<select v-model="current.menuDouble" v-on:change="current.menuDouble = current.menuDouble=='true'">
<option value="false">Single-Line</option>
<option value="true">Double-Line</option>
</select>
</td>
</tr>
<tr v-for="menu in def.menuOptions" v-bind:class="validateInput(current.menuOptions, menu.id, (current.menuDouble ? 2 : 1))">
<td class="label"><div class="stringId">{{menu.id}}</div></td>
<td class="value">
<div v-bind:class="{hidden : current.menuDouble}">
<div class="label">Menu Name (Single-Line)</div>
<div class="constraint">{{constraintString(menu, current.menuDouble)}}</div>
<div class="ref">{{referent.menuOptions[menu.id].text}}</div>
<div class="tran"><input type="text" v-model="current.menuOptions[menu.id].text" v-bind:class="{unchanged : current.menuOptions[menu.id].text == referent.menuOptions[menu.id].text, empty : current.menuOptions[menu.id].text == ''}"></div>
</div>
<div v-bind:class="{hidden : !current.menuDouble}">
<div class="label">Menu Name (Double-Line)</div>
<div class="constraint">{{constraintString(menu, current.menuDouble)}}</div>
<div class="ref">{{referent.menuOptions[menu.id].text2}}</div>
<div class="tran" v-bind:class="{unchanged : current.menuOptions[menu.id].text2[0] == referent.menuOptions[menu.id].text2[0] && current.menuOptions[menu.id].text2[1] == referent.menuOptions[menu.id].text2[1], empty : current.menuOptions[menu.id].text2[0] == '' || current.menuOptions[menu.id].text2[1] == ''}"><input type="text" v-model="current.menuOptions[menu.id].text2[0]"><input type="text" v-model="current.menuOptions[menu.id].text2[1]"></div>
</div>
<div class="label">Description</div>
<div class="ref">{{referent.menuOptions[menu.id].desc}}</div>
<div class="tran"><input type="text" v-model="current.menuOptions[menu.id].desc" v-bind:class="{unchanged : current.menuOptions[menu.id].desc == referent.menuOptions[menu.id].desc, empty : current.menuOptions[menu.id].desc == ''}"></div>
</td>
</tr>
</table>
<div class="footer">
<input type="button" value="Save" onclick="save()">
<input type="button" value="View" onclick="view()">
</div>
</div>
</div>
</body>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TS100 Translation Editor</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="translations_commons.js"></script>
<script src="translations_def.js"></script>
<script>
var app;
var defMap = {};
function save(){
saveJSON(app.current, "translation_"+app.current.languageCode.toLowerCase()+".json");
}
function view(){
showJSON(app.current, "translation_"+app.current.languageCode.toLowerCase()+".json");
}
function fileChanged(e) {
var target = e;
var id = target.id;
var file = target.files[0];
if (!file) {
return;
}
var fr = new FileReader();
fr.onload = function(e) {
try {
var json = JSON.parse(e.target.result);
} catch (ex) {
console.log(ex);
alert("Invalid JSON file: " + file.name);
return;
}
if (id == "referent-lang-file") {
if (checkTranslationFile(file.name)) {
app.referent = json;
app.meta.referentLoaded = true;
}
} else if (id == "current-lang-file") {
if (checkTranslationFile(file.name)) {
app.current = json;
if (!app.current.cyrillicGlyphs){
app.current.cyrillicGlyphs = false;
}
app.meta.currentLoaded = true;
}
}
synchronizeData();
}
fr.readAsText(file);
}
function synchronizeData() {
app.obsolete = {};
copyMissing(app.def.messages, app.referent.messages, app.current.messages);
copyMissing(app.def.characters, app.referent.characters, app.current.characters);
copyMissing(app.def.menuGroups, app.referent.menuGroups, app.current.menuGroups);
copyMissing(app.def.menuOptions, app.referent.menuOptions, app.current.menuOptions);
}
/**
* Copy all missing properties from referent to current
* for each entry in definition
*/
function copyMissing(defList, referentMap, currentMap) {
if (!isDefined(defList) || !isDefined(referentMap) || !isDefined(currentMap)) {
return;
}
var len = defList.length;
for (var i = 0; i < len; i++) {
var id = defList[i].id;
if (!isDefined(referentMap[id])) {
referentMap[id] = '';
}
if (!isDefined(currentMap[id])) {
currentMap[id] = referentMap[id];
}
}
processObsolete(defList, currentMap);
}
// Passes through all entries from the given map.
// If a corresponding entry is not found in the defList, it is removed from the map, and added into the obsolete map.
function processObsolete(defList, map) {
// Index list to map for faster search
var defMap = copyArrayToMap(defList);
Object.keys(map).forEach(function(key) {
if (!isDefined(defMap[key])) {
app.obsolete[key] = { id : key, value : map[key]};
delete map[key];
}
});
}
function length(obj, mode) {
if (!isDefined(mode) || mode == 0) {
// return direct length
return obj.length;
}
// return the longest length in text2 array
return Math.max(isDefinedNN(obj.text2[0]) ? obj.text2[0].length : 0, isDefinedNN(obj.text2[1]) ? obj.text2[1].length : 0);
}
function getAttribute(obj, attribute) {
var d = "2";
var v = obj[attribute+d];
if (isDefined(v))
return v;
return obj[attribute];
}
function loaded() {
app = new Vue({
el : '#app',
data : {
meta : {
referentLoaded : false,
currentLoaded : false,
},
def : {
},
referent : {
messages : {}
},
current : {
loaded: false,
},
obsolete : {},
},
methods : {
validateInput: function(valMap, id, mode) {
var d = defMap[id];
var vLen = 0;
if (!isDefined(mode))
mode = 0;
try {
// Sum for complex length
for (var i = 0; i < d.lenSum.fields.length; i++) {
vLen += length(valMap[d.lenSum.fields[i]], mode);
}
d = d.lenSum;
} catch (e) {
// Single field length
vLen = length(valMap[id], mode);
}
var maxLen = getAttribute(d, 'maxLen', mode == 2);
var minLen = getAttribute(d, 'minLen', mode == 2);
var len = getAttribute(d, 'len', mode == 2);
if (isNumber(maxLen) && vLen > maxLen
|| isNumber(minLen) && vLen < minLen
|| isNumber(len) && vLen != len
) {
return "invalid";
}
},
constraintString: function(e) {
var str = "";
var delim = "";
var v;
d = "2";
if (isDefinedNN(e.lenSum)) {
str = "len("+(e.lenSum.fields+"").replace(/,/g," + ")+") -> ";
e = e.lenSum;
}
v = getAttribute(e, 'len', d);
if (isNumber(v)) {
str += delim + "len=" + v;
delim = " and ";
}
v = getAttribute(e, 'minLen', d);
if (isNumber(v)) {
str += delim + "len>=" + v;
delim = " and ";
}
v = getAttribute(e, 'maxLen', d);
if (isNumber(v)) {
str += delim + "len<=" + v;
delim = " and ";
}
return str;
}
}
});
app.def = def;
copyArrayToMap(app.def.messages, defMap);
copyArrayToMap(app.def.characters, defMap);
copyArrayToMap(app.def.menuGroups, defMap);
copyArrayToMap(app.def.menuOptions, defMap);
}
window.onload=loaded;
</script>
<link href="translations.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="app">
<h1>TS100 Translation Editor<span v-if="meta.currentLoaded"> - {{ current.languageLocalName }} [{{current.languageCode}}]</span></h1>
<table class="header data">
<tr>
<td class="label">Referent Language</td>
<td class="value">
<input type="file" id="referent-lang-file" onchange="fileChanged(this)" accept=".json">
<span class="selected" v-if="meta.referentLoaded">{{ referent.languageLocalName }} [{{referent.languageCode}}]</span>
</td>
</tr>
<tr v-if="meta.referentLoaded">
<td class="label">Current Language</td>
<td class="value">
<input type="file" id="current-lang-file" onchange="fileChanged(this)" accept=".json">
<span class="selected" v-if="meta.currentLoaded">{{ current.languageLocalName }} [{{current.languageCode}}]</span>
</td>
</tr>
<tr v-if="meta.currentLoaded">
<td class="label">Local Language Code</td>
<td class="value"><input type="text" v-model="current.languageCode" maxlength="8" v-on:change="current.languageCode=current.languageCode.toUpperCase()" class="short"></td>
</tr>
<tr v-if="meta.currentLoaded">
<td class="label">Local Language Name</td>
<td class="value"><input type="text" v-model="current.languageLocalName" class="short"></td>
</tr>
<tr v-if="meta.currentLoaded">
<td class="label">Font table to use</td>
<td class="value">
<select v-model="current.cyrillicGlyphs" v-on:change="current.cyrillicGlyphs = current.cyrillicGlyphs=='true'">
<option value="false">Latin Extended</option>
<option value="true">Cyrillic Glyphs</option>
</select>
</td>
</tr>
</table>
<div v-if="def.messages && referent.messages && current.messages">
<div class="footer">
<input type="button" value="Save" onclick="save()">
<input type="button" value="View" onclick="view()">
</div>
<div v-if="Object.keys(obsolete).length > 0">
<h2>Obsolete</h2>
<table class="data">
<tr v-for="entry in obsolete">
<td class="label"><div class="stringId">{{entry.id}}</div></td>
<td class="value"><div class="ref">{{entry.value}}</div></td>
</tr>
</table>
</div>
<h2>Messages and Strings</h2>
<table class="data">
<tr v-for="message in def.messages" v-bind:class="validateInput(current.messages, message.id)">
<td class="label"><div class="stringId">{{message.id}}</div></td>
<td class="value">
<div class="constraint">{{constraintString(message)}}</div>
<div class="ref">{{referent.messages[message.id]}}</div>
<div class="note" v-if="message.note">{{message.note}}</div>
<div class="tran"><input :id="'in_'+message.id" type="text" v-model="current.messages[message.id]" v-bind:class="{unchanged : current.messages[message.id] == referent.messages[message.id], empty : current.messages[message.id]==''}"></div>
</td>
</tr>
</table>
<h2>Characters</h2>
<table class="data">
<tr v-for="char in def.characters" v-bind:class="validateInput(current.characters, char.id)">
<td class="label"><div class="stringId">{{char.id}}</div></td>
<td class="value">
<div class="constraint">{{constraintString(char)}}</div>
<div class="ref">{{referent.characters[char.id]}}</div>
<div class="tran"><input type="text" v-model="current.characters[char.id]" v-bind:class="{unchanged : current.characters[char.id] == referent.characters[char.id], empty : current.characters[char.id].length != 1}"></div>
</td>
</tr>
</table>
<h2>Menu Groups</h2>
<table class="data">
<tr v-for="menu in def.menuGroups" v-bind:class="validateInput(current.menuGroups, menu.id, 2)">
<td class="label"><div class="stringId">{{menu.id}}</div></td>
<td class="value">
<div class="label">Menu Name</div>
<div class="constraint">{{constraintString(menu)}}</div>
<div class="ref">{{referent.menuGroups[menu.id].text2}}</div>
<div class="tran" v-bind:class="{unchanged : current.menuGroups[menu.id].text2[0] == referent.menuGroups[menu.id].text2[0] && current.menuGroups[menu.id].text2[1] == referent.menuGroups[menu.id].text2[1], empty : current.menuGroups[menu.id].text2[0] == '' || current.menuGroups[menu.id].text2[1] == ''}"><input type="text" v-model="current.menuGroups[menu.id].text2[0]"><input type="text" v-model="current.menuGroups[menu.id].text2[1]"></div>
<div class="label">Description</div>
<div class="ref">{{referent.menuGroups[menu.id].desc}}</div>
<div class="tran"><input type="text" v-model="current.menuGroups[menu.id].desc" v-bind:class="{unchanged : current.menuGroups[menu.id].desc == referent.menuGroups[menu.id].desc, empty : current.menuGroups[menu.id].desc == ''}"></div>
</td>
</tr>
</table>
<h2>Menu Options</h2>
<table class="data">
<tr v-for="menu in def.menuOptions" v-bind:class="validateInput(current.menuOptions, menu.id, 2)">
<td class="label"><div class="stringId">{{menu.id}}</div></td>
<td class="value">
<div v-bind:class="{hidden : false}">
<div class="label">Menu Name (Double-Line)</div>
<div class="constraint">{{constraintString(menu)}}</div>
<div class="ref">{{referent.menuOptions[menu.id].text2}}</div>
<div class="tran" v-bind:class="{unchanged : current.menuOptions[menu.id].text2[0] == referent.menuOptions[menu.id].text2[0] && current.menuOptions[menu.id].text2[1] == referent.menuOptions[menu.id].text2[1], empty : current.menuOptions[menu.id].text2[0] == '' || current.menuOptions[menu.id].text2[1] == ''}"><input type="text" v-model="current.menuOptions[menu.id].text2[0]"><input type="text" v-model="current.menuOptions[menu.id].text2[1]"></div>
</div>
<div class="label">Description</div>
<div class="ref">{{referent.menuOptions[menu.id].desc}}</div>
<div class="tran"><input type="text" v-model="current.menuOptions[menu.id].desc" v-bind:class="{unchanged : current.menuOptions[menu.id].desc == referent.menuOptions[menu.id].desc, empty : current.menuOptions[menu.id].desc == ''}"></div>
</td>
</tr>
</table>
<div class="footer">
<input type="button" value="Save" onclick="save()">
<input type="button" value="View" onclick="view()">
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,325 +1,322 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TS100 Translation Parser</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="translations_commons.js"></script>
<script src="translations_def.js"></script>
<script>
var app;
var defMap = {};
var langMap = {};
var lang;
var defMsgMap;
var defCharMap;
var defGrpMap;
var defOptMap;
function save(langCode){
saveJSON(langMap[langCode], "translation_"+langCode.toLowerCase()+".json");
}
function view(langCode){
showJSON(langMap[langCode], "translation_"+langCode.toLowerCase()+".json");
}
function translationFileSelected(e) {
var target = e;
var id = target.id;
var file = target.files[0];
if (!file) {
return;
}
var fr = new FileReader();
fr.onload = function(e) {
parseTranslationFile(file.name, e.target.result);
}
fr.readAsText(file);
}
function parseTranslationFile(name, src) {
// remove multiline comments
src = src.replace(/\/\*[\s\S.]*?\*\//mg, "");
// remove single-line comments
src = src.replace(/\/\/.*/mg, "");
// remove empty lines
src = src.replace(/^\s*\n/gm, "");
var langCode = "";
var srcLines = src.split("\n");
var reMessage = /const\s+char\s*\*\s+([\w\d]+)\s*=\s*"(.*)"/;
var reSettingsDescStart = /const\s+char\s*\*\s+SettingsDescriptions\[/;
var reSettingsNamesStart = /const\s+char\s*\*\s+SettingsShortNames\[/;
var reSettingsMenuDescStart = /const\s+char\s*\*\s+SettingsMenuEntriesDescriptions\[/;
var reChar = /const\s+char\s+([\w\d]+)\s*=\s*'(\w)'/;
var reMenuMode = /SettingsShortNameType\s*=\s*SHORT_NAME_(\w+)_LINE/;
var reMenuStart = /\s*const\s+char\s*\*\s+SettingsMenuEntries\[/;
// var reString = /^\s*"(.*)"/;
var reString = /"(.*)"/;
var reSingleLine = /{\s*"(.*)"\s*}/;
var reDoubleLine = /{\s*"(.*)"\s*,\s*"(.*)"\s*}/;
var mode = '';
var entryIndex = 0;
for (var li = 0; li < srcLines.length; li++) {
// trim lines
line = srcLines[li] = srcLines[li].trim();
// if entering a new lang block
if (startsWith(line, "#ifdef LANG_")) {
mode = 'new-language';
langCode = line.substring(12);
lang = langMap[langCode];
// use existing or instantiate new
if (!isDefined(lang)) {
lang = {
languageCode: langCode,
cyrillicGlyphs: false,
messages: {},
characters: {},
menuDouble : false,
menuGroups: {},
menuOptions: {}
};
langMap[langCode] = lang;
app.languages[app.languages.length] = langCode;
}
entryIndex = 0;
continue;
}
// Use Cyrillic glyphs
if (startsWith(line, "#define CYRILLIC_GLYPHS")) {
lang.cyrillicGlyphs = true;
entryIndex = 0;
continue;
}
// Menu type
reMenuMode.lastIndex = 0;
match = reMenuMode.exec(line);
if (match) {
lang.menuDouble = match[1] == 'DOUBLE';
entryIndex = 0;
continue;
}
// Messages
reMessage.lastIndex = 0;
match = reMessage.exec(line);
if (match) {
lang.messages[match[1]] = xunescape(match[2]);
entryIndex = 0;
continue;
}
// Chars descriptions
reChar.lastIndex = 0;
match = reChar.exec(line);
if (match) {
// found description block start
mode = 'char';
lang.characters[match[1]] = xunescape(match[2]);
entryIndex = 0;
continue;
}
// Settings descriptions
reSettingsDescStart.lastIndex = 0;
match = reSettingsDescStart.exec(line);
if (match) {
// found description block start
mode = 'settingsDesc';
entryIndex = 0;
continue;
}
reSettingsNamesStart.lastIndex = 0;
match = reSettingsNamesStart.exec(line);
if (match) {
// found description block start
mode = 'settingsNames';
entryIndex = 0;
continue;
}
reMenuStart.lastIndex = 0;
match = reMenuStart.exec(line);
if (match) {
// found description block start
mode = 'menu';
entryIndex = 0;
continue;
}
reSettingsMenuDescStart.lastIndex = 0;
match = reSettingsMenuDescStart.exec(line);
if (match) {
// found description block start
mode = 'menuDesc';
entryIndex = 0;
continue;
}
if (mode == 'menu') {
// processing menu group names
reString.lastIndex = 0;
match = reString.exec(line);
if (match) {
// found description string
var entry = getMenuGroup(entryIndex);
var m = match[1].split("\\n");
entry.text2[0] = xunescape(m[0]);
entry.text2[1] = xunescape(m[1]);
entryIndex++;
}
} else if (mode == 'menuDesc') {
// processing menu group descriptions
reString.lastIndex = 0;
match = reString.exec(line);
if (match) {
// found description string
var entry = getMenuGroup(entryIndex);
entry.desc = xunescape(match[1]);
entryIndex++;
}
} else if (mode == 'settingsDesc') {
// processing option descriptions
reString.lastIndex = 0;
match = reString.exec(line);
if (match) {
// found description string
var entry = getMenuOption(entryIndex);
entry.desc = xunescape(match[1]);
entryIndex++;
}
} else if (mode == 'settingsNames') {
reDoubleLine.lastIndex = 0;
match = reDoubleLine.exec(line);
if (match) {
var entry = getMenuOption(entryIndex);
entry.text2[0] = xunescape(match[1]);
entry.text2[1] = xunescape(match[2]);
entryIndex++;
} else {
reSingleLine.lastIndex = 0;
match = reSingleLine.exec(line);
if (match) {
var entry = getMenuOption(entryIndex);
entry.text = xunescape(match[1]);
entryIndex++;
}
}
}
}
app.done = 1;
}
function getMenuOption(entryIndex) {
var optionDef = def.menuOptions[entryIndex];
if (!isDefined(optionDef)) {
var s = "Could not find menu option with index "+entryIndex;
alert(s);
throw s;
}
var id = optionDef.id;
var entry = lang.menuOptions[id];
if (!isDefined(entry)) {
entry =
{
"text": "",
"text2": ["", ""],
"desc": ""
}
lang.menuOptions[id] = entry;
}
return entry;
}
function getMenuGroup(entryIndex) {
var optionDef = def.menuGroups[entryIndex];
if (!isDefined(optionDef)) {
var s = "Could not find menu group with index "+entryIndex;
alert(s);
throw s;
}
var id = optionDef.id;
var entry = lang.menuGroups[id];
if (!isDefined(entry)) {
entry =
{
"text2": ["", ""],
"desc": ""
}
lang.menuGroups[id] = entry;
}
return entry;
}
function markSaved(lang) {
document.getElementById("row_"+lang).classList.add("saved");
}
function loaded() {
app = new Vue({
el : '#app',
data : {
languages: [],
done : false,
def : {
}
},
methods : {
vSave : function(lang) {
save(lang);
markSaved(lang);
},
vView : function(lang) {
view(lang);
markSaved(lang);
}
}
});
app.def = def;
defMsgMap = copyArrayToMap(app.def.messages);
defCharMap = copyArrayToMap(app.def.characters);
defGrpMap = copyArrayToMap(app.def.menuGroups);
defOptMap = copyArrayToMap(app.def.menuOptions);
}
window.onload=loaded;
</script>
<link href="translations.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="app">
<h1>TS100 Translation Parser</h1>
<table class="header data">
<tr>
<td class="label">Translation.cpp</td>
<td class="value">
<input type="file" id="translation-cpp-file" onchange="translationFileSelected(this)" accept=".cpp">
</td>
</tr>
</table>
<div class="data" v-if="done">
<div class="value" v-for="lang in languages" :id="'row_'+lang">
<input type="button" :value="'Save '+lang" v-on:click="vSave(lang)">
<input type="button" :value="'View '+lang" v-on:click="vView(lang)">
</div>
</div>
</div>
</body>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TS100 Translation Parser</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="translations_commons.js"></script>
<script src="translations_def.js"></script>
<script>
var app;
var defMap = {};
var langMap = {};
var lang;
var defMsgMap;
var defCharMap;
var defGrpMap;
var defOptMap;
function save(langCode){
saveJSON(langMap[langCode], "translation_"+langCode.toLowerCase()+".json");
}
function view(langCode){
showJSON(langMap[langCode], "translation_"+langCode.toLowerCase()+".json");
}
function translationFileSelected(e) {
var target = e;
var id = target.id;
var file = target.files[0];
if (!file) {
return;
}
var fr = new FileReader();
fr.onload = function(e) {
parseTranslationFile(file.name, e.target.result);
}
fr.readAsText(file);
}
function parseTranslationFile(name, src) {
// remove multiline comments
src = src.replace(/\/\*[\s\S.]*?\*\//mg, "");
// remove single-line comments
src = src.replace(/\/\/.*/mg, "");
// remove empty lines
src = src.replace(/^\s*\n/gm, "");
var langCode = "";
var srcLines = src.split("\n");
var reMessage = /const\s+char\s*\*\s+([\w\d]+)\s*=\s*"(.*)"/;
var reSettingsDescStart = /const\s+char\s*\*\s+SettingsDescriptions\[/;
var reSettingsNamesStart = /const\s+char\s*\*\s+SettingsShortNames\[/;
var reSettingsMenuDescStart = /const\s+char\s*\*\s+SettingsMenuEntriesDescriptions\[/;
var reChar = /const\s+char\s+([\w\d]+)\s*=\s*'(\w)'/;
var reMenuMode = /SettingsShortNameType\s*=\s*SHORT_NAME_(\w+)_LINE/;
var reMenuStart = /\s*const\s+char\s*\*\s+SettingsMenuEntries\[/;
// var reString = /^\s*"(.*)"/;
var reString = /"(.*)"/;
var reSingleLine = /{\s*"(.*)"\s*}/;
var reDoubleLine = /{\s*"(.*)"\s*,\s*"(.*)"\s*}/;
var mode = '';
var entryIndex = 0;
for (var li = 0; li < srcLines.length; li++) {
// trim lines
line = srcLines[li] = srcLines[li].trim();
// if entering a new lang block
if (startsWith(line, "#ifdef LANG_")) {
mode = 'new-language';
langCode = line.substring(12);
lang = langMap[langCode];
// use existing or instantiate new
if (!isDefined(lang)) {
lang = {
languageCode: langCode,
cyrillicGlyphs: false,
messages: {},
characters: {},
menuGroups: {},
menuOptions: {}
};
langMap[langCode] = lang;
app.languages[app.languages.length] = langCode;
}
entryIndex = 0;
continue;
}
// Use Cyrillic glyphs
if (startsWith(line, "#define CYRILLIC_GLYPHS")) {
lang.cyrillicGlyphs = true;
entryIndex = 0;
continue;
}
// Menu type
reMenuMode.lastIndex = 0;
match = reMenuMode.exec(line);
if (match) {
entryIndex = 0;
continue;
}
// Messages
reMessage.lastIndex = 0;
match = reMessage.exec(line);
if (match) {
lang.messages[match[1]] = xunescape(match[2]);
entryIndex = 0;
continue;
}
// Chars descriptions
reChar.lastIndex = 0;
match = reChar.exec(line);
if (match) {
// found description block start
mode = 'char';
lang.characters[match[1]] = xunescape(match[2]);
entryIndex = 0;
continue;
}
// Settings descriptions
reSettingsDescStart.lastIndex = 0;
match = reSettingsDescStart.exec(line);
if (match) {
// found description block start
mode = 'settingsDesc';
entryIndex = 0;
continue;
}
reSettingsNamesStart.lastIndex = 0;
match = reSettingsNamesStart.exec(line);
if (match) {
// found description block start
mode = 'settingsNames';
entryIndex = 0;
continue;
}
reMenuStart.lastIndex = 0;
match = reMenuStart.exec(line);
if (match) {
// found description block start
mode = 'menu';
entryIndex = 0;
continue;
}
reSettingsMenuDescStart.lastIndex = 0;
match = reSettingsMenuDescStart.exec(line);
if (match) {
// found description block start
mode = 'menuDesc';
entryIndex = 0;
continue;
}
if (mode == 'menu') {
// processing menu group names
reString.lastIndex = 0;
match = reString.exec(line);
if (match) {
// found description string
var entry = getMenuGroup(entryIndex);
var m = match[1].split("\\n");
entry.text2[0] = xunescape(m[0]);
entry.text2[1] = xunescape(m[1]);
entryIndex++;
}
} else if (mode == 'menuDesc') {
// processing menu group descriptions
reString.lastIndex = 0;
match = reString.exec(line);
if (match) {
// found description string
var entry = getMenuGroup(entryIndex);
entry.desc = xunescape(match[1]);
entryIndex++;
}
} else if (mode == 'settingsDesc') {
// processing option descriptions
reString.lastIndex = 0;
match = reString.exec(line);
if (match) {
// found description string
var entry = getMenuOption(entryIndex);
entry.desc = xunescape(match[1]);
entryIndex++;
}
} else if (mode == 'settingsNames') {
reDoubleLine.lastIndex = 0;
match = reDoubleLine.exec(line);
if (match) {
var entry = getMenuOption(entryIndex);
entry.text2[0] = xunescape(match[1]);
entry.text2[1] = xunescape(match[2]);
entryIndex++;
} else {
reSingleLine.lastIndex = 0;
match = reSingleLine.exec(line);
if (match) {
var entry = getMenuOption(entryIndex);
entry.text = xunescape(match[1]);
entryIndex++;
}
}
}
}
app.done = 1;
}
function getMenuOption(entryIndex) {
var optionDef = def.menuOptions[entryIndex];
if (!isDefined(optionDef)) {
var s = "Could not find menu option with index "+entryIndex;
alert(s);
throw s;
}
var id = optionDef.id;
var entry = lang.menuOptions[id];
if (!isDefined(entry)) {
entry =
{
"text2": ["", ""],
"desc": ""
}
lang.menuOptions[id] = entry;
}
return entry;
}
function getMenuGroup(entryIndex) {
var optionDef = def.menuGroups[entryIndex];
if (!isDefined(optionDef)) {
var s = "Could not find menu group with index "+entryIndex;
alert(s);
throw s;
}
var id = optionDef.id;
var entry = lang.menuGroups[id];
if (!isDefined(entry)) {
entry =
{
"text2": ["", ""],
"desc": ""
}
lang.menuGroups[id] = entry;
}
return entry;
}
function markSaved(lang) {
document.getElementById("row_"+lang).classList.add("saved");
}
function loaded() {
app = new Vue({
el : '#app',
data : {
languages: [],
done : false,
def : {
}
},
methods : {
vSave : function(lang) {
save(lang);
markSaved(lang);
},
vView : function(lang) {
view(lang);
markSaved(lang);
}
}
});
app.def = def;
defMsgMap = copyArrayToMap(app.def.messages);
defCharMap = copyArrayToMap(app.def.characters);
defGrpMap = copyArrayToMap(app.def.menuGroups);
defOptMap = copyArrayToMap(app.def.menuOptions);
}
window.onload=loaded;
</script>
<link href="translations.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="app">
<h1>TS100 Translation Parser</h1>
<table class="header data">
<tr>
<td class="label">Translation.cpp</td>
<td class="value">
<input type="file" id="translation-cpp-file" onchange="translationFileSelected(this)" accept=".cpp">
</td>
</tr>
</table>
<div class="data" v-if="done">
<div class="value" v-for="lang in languages" :id="'row_'+lang">
<input type="button" :value="'Save '+lang" v-on:click="vSave(lang)">
<input type="button" :value="'View '+lang" v-on:click="vView(lang)">
</div>
</div>
</div>
</body>
</html>

View File

@@ -125,27 +125,6 @@ def getConstants():
return consants
def getTipModelEnumTS80():
constants = []
constants.append("B02")
constants.append("D25")
constants.append("TS80") # end of miniware
constants.append("User") # User
return constants
def getTipModelEnumTS100():
constants = []
constants.append("B02")
constants.append("D24")
constants.append("BC2")
constants.append(" C1")
constants.append("TS100") # end of miniware
constants.append("BC2")
constants.append("Hakko") # end of hakko
constants.append("User")
return constants
def getDebugMenu():
constants = []
@@ -188,11 +167,8 @@ def getLetterCounts(defs, lang):
obj = lang['menuOptions']
for mod in defs['menuOptions']:
eid = mod['id']
if lang['menuDouble']:
textList.append(obj[eid]['text2'][0])
textList.append(obj[eid]['text2'][1])
else:
textList.append(obj[eid]['text'])
textList.append(obj[eid]['text2'][0])
textList.append(obj[eid]['text2'][1])
obj = lang['menuGroups']
for mod in defs['menuGroups']:
@@ -207,8 +183,6 @@ def getLetterCounts(defs, lang):
constants = getConstants()
for x in constants:
textList.append(x[1])
textList.extend(getTipModelEnumTS100())
textList.extend(getTipModelEnumTS80())
textList.extend(getDebugMenu())
# collapse all strings down into the composite letters and store totals for these
@@ -329,17 +303,19 @@ def writeLanguage(languageCode, defs, f):
f.write(to_unicode("const char* SettingsDescriptions[] = {\n"))
maxLen = 25
index =0
for mod in defs['menuOptions']:
eid = mod['id']
if 'feature' in mod:
f.write(to_unicode("#ifdef " + mod['feature'] + "\n"))
f.write(to_unicode(" /* " + eid.ljust(maxLen)[:maxLen] + " */ "))
f.write(to_unicode(" /* ["+"{:02d}".format(index)+"] " + eid.ljust(maxLen)[:maxLen] + " */ "))
f.write(
to_unicode("\"" +
convStr(symbolConversionTable, (obj[eid]['desc'])) +
"\"," + "//{} \n".format(obj[eid]['desc'])))
if 'feature' in mod:
f.write(to_unicode("#endif\n"))
index=index+1
f.write(to_unicode("};\n\n"))
@@ -381,20 +357,6 @@ def writeLanguage(languageCode, defs, f):
convStr(symbolConversionTable, x[1]) + "\";" + "//{} \n".format(x[1])))
f.write(to_unicode("\n"))
# Write out tip model strings
f.write(to_unicode("const char* TipModelStrings[] = {\n"))
f.write(to_unicode("#ifdef MODEL_TS100\n"))
for c in getTipModelEnumTS100():
f.write(to_unicode("\t \"" + convStr(symbolConversionTable,
c) + "\"," + "//{} \n".format(c)))
f.write(to_unicode("#else\n"))
for c in getTipModelEnumTS80():
f.write(to_unicode("\t \"" + convStr(symbolConversionTable,
c) + "\"," + "//{} \n".format(c)))
f.write(to_unicode("#endif\n"))
f.write(to_unicode("};\n\n"))
# Debug Menu
f.write(to_unicode("const char* DebugMenu[] = {\n"))
@@ -404,39 +366,28 @@ def writeLanguage(languageCode, defs, f):
c) + "\"," + "//{} \n".format(c)))
f.write(to_unicode("};\n\n"))
# ----- Menu Options
# Menu type
f.write(
to_unicode(
"const enum ShortNameType SettingsShortNameType = SHORT_NAME_" +
("DOUBLE" if lang['menuDouble'] else "SINGLE") + "_LINE;\n"))
# ----- Writing SettingsDescriptions
obj = lang['menuOptions']
f.write(to_unicode("const char* SettingsShortNames[][2] = {\n"))
maxLen = 25
index = 0
for mod in defs['menuOptions']:
eid = mod['id']
if 'feature' in mod:
f.write(to_unicode("#ifdef " + mod['feature'] + "\n"))
f.write(to_unicode(" /* " + eid.ljust(maxLen)[:maxLen] + " */ "))
if lang['menuDouble']:
f.write(
to_unicode(
"{ \"" +
convStr(symbolConversionTable, (obj[eid]['text2'][0])) +
"\", \"" +
convStr(symbolConversionTable, (obj[eid]['text2'][1])) +
"\" }," + "//{} \n".format(obj[eid]['text2'])))
else:
f.write(
to_unicode("{ \"" +
convStr(symbolConversionTable, (obj[eid]['text'])) +
"\" }," + "//{} \n".format(obj[eid]['text'])))
f.write(to_unicode(" /* ["+"{:02d}".format(index)+"] " + eid.ljust(maxLen)[:maxLen] + " */ "))
f.write(
to_unicode(
"{ \"" +
convStr(symbolConversionTable, (obj[eid]['text2'][0])) +
"\", \"" +
convStr(symbolConversionTable, (obj[eid]['text2'][1])) +
"\" }," + "//{} \n".format(obj[eid]['text2'])))
if 'feature' in mod:
f.write(to_unicode("#endif\n"))
index = index + 1
f.write(to_unicode("};\n\n"))

View File

@@ -3,10 +3,10 @@
"languageLocalName": "Български",
"cyrillicGlyphs": true,
"messages": {
"SettingsCalibrationDone": "Calibration done!",
"SettingsCalibrationWarning": "Уверете се, че човката на поялника е със стайна температура преди да продължите!",
"SettingsCalibrationDone": "Калибрацията завършена!",
"SettingsCalibrationWarning": "Уверете се, че върха на поялника е със стайна температура преди да продължите!",
"SettingsResetWarning": "Сигурни ли сте, че искате да върнете фабричните настройки?",
"UVLOWarningString": "Ниско V!",
"UVLOWarningString": "Ниско DC Напрежение",
"UndervoltageString": "Ниско Напрежение",
"InputVoltageString": "Входно V: ",
"WarningTipTempString": "Темп.: ",
@@ -17,11 +17,13 @@
"WarningAdvancedString": "ВНИМАНИЕ! ТОПЛО!",
"SleepingTipAdvancedString": "Връх:",
"IdleTipString": "Връх:",
"IdleSetString": " Set:",
"TipDisconnectedString": "ВРЪХ ЛОША ВРЪЗКА",
"IdleSetString": " Настройка:",
"TipDisconnectedString": "ПРЕКЪСНАТ ВРЪХ",
"SolderingAdvancedPowerPrompt": "Захранване: ",
"OffString": "Off",
"ResetOKMessage": "Reset OK"
"OffString": "Изкл.",
"ResetOKMessage": "Нулиране завършено",
"YourGainMessage": "Усилване:",
"SettingsResetMessage": "Настройките бяха\nнулирани!"
},
"characters": {
"SettingRightChar": "R",
@@ -34,7 +36,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,228 +68,186 @@
},
"menuOptions": {
"PowerSource": {
"text": "",
"text2": [
"text2": [
"Източник",
"захранване"
],
"desc": "Източник на захранване. Минимално напрежение. <DC 10V> <S 3.3V за клетка>"
},
"SleepTemperature": {
"text": "",
"text2": [
"text2": [
"Темп.",
"сън"
],
"desc": "Температура при режим \"сън\" <C>"
},
"SleepTimeout": {
"text": "",
"text2": [
"text2": [
"Време",
"сън"
],
"desc": "Включване в режим \"сън\" след: <Минути/Секунди>"
},
"ShutdownTimeout": {
"text": "",
"text2": [
"text2": [
"Време",
"изкл."
],
"desc": "Изключване след <Минути>"
},
"MotionSensitivity": {
"text": "",
"text2": [
"text2": [
"Усещане",
"за движение"
],
"desc": "Усещане за движение <0.Изключено 1.Слабо 9.Силно>"
},
"TemperatureUnit": {
"text": "",
"text2": [
"text2": [
"Единици за",
"температура"
],
"desc": "Единици за температура <C=Целзии F=Фаренхайт>"
},
"AdvancedIdle": {
"text": "",
"text2": [
"text2": [
"Детайлен",
"екран в покой"
],
"desc": "Покажи детайлна информация със ситен шрифт на екрана в режим на покой."
},
"DisplayRotation": {
"text": "",
"text2": [
"text2": [
"Ориентация",
"на дисплея"
],
"desc": "Ориентация на дисплея <A. Автоматично L. Лява Ръка R. Дясна Ръка>"
},
"BoostEnabled": {
"text": "",
"text2": [
"Турбо режим",
"пуснат"
],
"desc": "Ползвай предния бутон за \"турбо\" режим с температура до 450C при запояване"
},
"BoostTemperature": {
"text": "",
"text2": [
"text2": [
"Турбо",
"темп."
],
"desc": "Температура за \"турбо\" режим"
},
"AutoStart": {
"text": "",
"text2": [
"text2": [
"Автоматичен",
"работен режим"
],
"desc": "Режим на поялника при включване на захранването. T=Работен, S=Сън, F=Изключен"
},
"CooldownBlink": {
"text": "",
"text2": [
"text2": [
"Мигай при",
"топъл поялник"
],
"desc": "След изключване от работен режим, индикатора за температура да мига докато човката на поялника все още е топла"
},
"TemperatureCalibration": {
"text": "",
"text2": [
"text2": [
"Калибриране",
"температура?"
],
"desc": "Калибриране на температурата"
},
"SettingsReset": {
"text": "",
"text2": [
"text2": [
"Фабрични",
"настройки?"
],
"desc": "Връщане на фабрични настройки"
},
"VoltageCalibration": {
"text": "",
"text2": [
"text2": [
"Калибриране",
"напрежение?"
],
"desc": "Калибриране на входното напрежение (VIN). Задръжте бутонa за изход"
"desc": "Калибриране на входното напрежение. Задръжте бутонa за изход"
},
"AdvancedSoldering": {
"text": "",
"text2": [
"text2": [
"Детайлен",
"работен екран"
],
"desc": "Детайлна информация в работен режим при запояване"
},
"ScrollingSpeed": {
"text": "",
"text2": [
"text2": [
"Скорост",
"на текста"
],
"desc": "Скорост на движение на този текст"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"Tip",
"Model"
"text2": [
"Модел",
"на връх"
],
"desc": "Tip Model selection"
"desc": "Избор на модел на връх"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"Simple",
"Calibration"
"text2": [
"Бърза",
"калибрация"
],
"desc": "Simple Calibration using Hot water"
"desc": "Бърза калибрация с използване на гореща вода"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"Advanced",
"Calibration"
"text2": [
"Прецизна",
"калибрация"
],
"desc": "Advanced calibration using thermocouple on the tip"
"desc": "Прецизна калибрация с използване на термо-двойка на върха на поялника"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"Power",
"Wattage"
"text2": [
"Мощност на",
"захранване"
],
"desc": "Power Wattage of the power adapter used"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
"desc": "Мощност на избраното захранване"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"Power",
"Limit"
"text2": [
"Лимит на",
"мощност"
],
"desc": "Maximum power the iron can use <Watts>"
"desc": "Максимална мощност на поялника <W>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"Key +-",
"reverse?"
"text2": [
"Размяна",
"бутони +-?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
"desc": "Обръщане на бутоните \"+\" и \"-\" за промяна на температурата на върха на поялника"
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"Temp change",
"short?"
"text2": [
"Промяна T",
"бързо?"
],
"desc": "Temperature change steps on short button press!"
"desc": "Промяна на температура при бързо натискане на бутон!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"Temp change",
"long?"
"text2": [
"Промяна Т",
"задържане?"
],
"desc": "Temperature change steps on long button press!"
"desc": "Промяна на температура при задържане на бутон!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"Power",
"Pulse W"
"text2": [
"Захранващ",
"импулс"
],
"desc": "Keep awake pulse power intensity"
"desc": "Поддържане на интензивност на захранващия импулс"
},
"TipGain": {
"text": "TG",
"text2": [
"Modify",
"tip gain"
"text2": [
"Промяна",
"сила връх"
],
"desc": "Tip gain"
"desc": "Усилване на върха на поялника"
}
}
}

118
Translation Editor/translation_cs.json Normal file → Executable file
View File

@@ -22,7 +22,8 @@
"SolderingAdvancedPowerPrompt": "Ohřev: ",
"OffString": "Vyp",
"ResetOKMessage": "Reset OK",
"YourGainMessage": "Zisk:"
"YourGainMessage": "Zisk:",
"SettingsResetMessage": "Tov. nas. obnov."
},
"characters": {
"SettingRightChar": "P",
@@ -35,7 +36,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -68,143 +68,118 @@
},
"menuOptions": {
"PowerSource": {
"text": "",
"text2": [
"text2": [
"Zdroj",
"napájení"
],
"desc": "Při nižším napětí ukončí pájení <DC=10V, ?S=?x3.3V pro LiPo, LiIon...>."
},
"SleepTemperature": {
"text": "",
"text2": [
"text2": [
"Teplota v",
"r. spánku"
],
"desc": "Teplota v režimu spánku."
},
"SleepTimeout": {
"text": "",
"text2": [
"text2": [
"Čas do",
"r. spánku"
],
"desc": "Čas do režimu spánku <Minut/Sekund>."
},
"ShutdownTimeout": {
"text": "",
"text2": [
"text2": [
"Čas do",
"vypnutí"
],
"desc": "Čas do automatického vypnutí <Minut>."
},
"MotionSensitivity": {
"text": "",
"text2": [
"text2": [
"Citlivost",
"det. pohybu"
],
"desc": "Citlivost detekce pohybu <0=Vyp, 1=Min, ... 9=Max>."
},
"TemperatureUnit": {
"text": "",
"text2": [
"text2": [
"Jednotky",
"teploty"
],
"desc": "Jednotky měření teploty <C=Celsius, F=Fahrenheit>."
},
"AdvancedIdle": {
"text": "",
"text2": [
"text2": [
"Podrobnosti",
"na vých. obr."
],
"desc": "Zobrazit podrobnosti na výchozí obrazovce?"
},
"DisplayRotation": {
"text": "",
"text2": [
"text2": [
"Orientace",
"obrazovky"
],
"desc": "Orientace obrazovky <A=Auto, L=Levák, P=Pravák>."
},
"BoostEnabled": {
"text": "",
"text2": [
"Povolit",
"boost"
],
"desc": "Povolit boost podržením předního tlačítka při pájení?"
},
"BoostTemperature": {
"text": "",
"text2": [
"text2": [
"Teplota v",
"r. boost"
],
"desc": "Teplota v režimu boost."
},
"AutoStart": {
"text": "",
"text2": [
"text2": [
"Automatický",
"start"
],
"desc": "Při startu ihned nahřát hrot?"
},
"CooldownBlink": {
"text": "",
"text2": [
"text2": [
"Blikáni při",
"chladnutí"
],
"desc": "Blikání teploty při chladnutí, dokud je hrot horký?"
},
"TemperatureCalibration": {
"text": "",
"text2": [
"text2": [
"Kalibrovat",
"teplotu?"
],
"desc": "Kalibrace měření teploty."
},
"SettingsReset": {
"text": "",
"text2": [
"text2": [
"Tovární",
"nastavení?"
],
"desc": "Obnovení továrního nastavení."
},
"VoltageCalibration": {
"text": "",
"text2": [
"text2": [
"Kalibrovat",
"vstupní napětí?"
],
"desc": "Kalibrace vstupního napětí. Tlačítky uprav, podržením potvrď."
},
"AdvancedSoldering": {
"text": "",
"text2": [
"text2": [
"Podrobnosti",
"při pájení"
],
"desc": "Zobrazit podrobnosti při pájení?"
},
"ScrollingSpeed": {
"text": "",
"text2": [
"text2": [
"Rychlost",
"popisků"
],
"desc": "Rychlost posuvu popisků podobných tomuto <P=Pomalu, R=Rychle>"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"Model",
"hrotu"
@@ -212,7 +187,6 @@
"desc": "Výběr modelu hrotu."
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"Jednoduchá",
"kalibrace"
@@ -220,7 +194,6 @@
"desc": "Jednoduchá kalibrace pomocí horké vody."
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"Pokročilá",
"kalibrace"
@@ -228,68 +201,53 @@
"desc": "Pokročilá kalibrace pomocí termočlánku na hrotu."
},
"PowerInput": {
"text": "PWRW",
"text2": [
"Výkon",
"ve wattech"
],
"desc": "Výkon použítého napájecího adaptéru ve wattech."
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"Power",
"Limit"
"Omezení",
"Výkonu"
],
"desc": "Maximum power the iron can use <Watts>"
"desc": "Maximální příkon <Watty>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"Key +-",
"reverse?"
"Prohodit",
"tl. +-?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
"desc": "Prohodí tlačítka plus a minus pro změnu teploty hrotu."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"Temp change",
"short?"
"Krok teploty",
"krátký?"
],
"desc": "Temperature change steps on short button press!"
"desc": "Velikost skoku při změně teploty krátkým stiskem tlačítka!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"Temp change",
"long?"
"Krok teploty",
"dlouhý?"
],
"desc": "Temperature change steps on long button press!"
"desc": "Velikost skoku při změně teploty dlouhým stiskem tlačítka!"
},
"PowerPulsePower":{
"text": "POWPLS",
"PowerPulsePower": {
"text2": [
"Power",
"Pulse W"
"Intenzita",
"Výkon. pulsu"
],
"desc": "Keep awake pulse power intensity"
"desc": "Puls pro udržení zařízení v chodu (kvůli power bankám)."
},
"TipGain": {
"text": "TG",
"text2": [
"Modify",
"tip gain"
"Změnit",
"zisk hr."
],
"desc": "Tip gain"
"desc": "Zisk hrotu (měření)"
}
}
}
}

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "S"
},
"menuDouble": false,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,143 +66,118 @@
},
"menuOptions": {
"PowerSource": {
"text": "PWRSC",
"text2": [
"",
""
"Power",
"source"
],
"desc": "Strømforsyning. Indstil Cutoff Spændingen. <DC 10V <S 3.3V per cell"
},
"SleepTemperature": {
"text": "STMP",
"text2": [
"",
""
"Sleep",
"temp"
],
"desc": "Dvale Temperatur <C"
"desc": "Dvale Temperatur <C>"
},
"SleepTimeout": {
"text": "STME",
"text2": [
"",
""
"Sleep",
"timeout"
],
"desc": "Dvale Timeout <Minutter/Sekunder"
},
"ShutdownTimeout": {
"text": "SHTME",
"text2": [
"",
""
"Shutdown",
"timeout"
],
"desc": "sluknings Timeout <Minutter"
},
"MotionSensitivity": {
"text": "MSENSE",
"text2": [
"",
""
"Motion",
"sensitivity"
],
"desc": "Bevægelsesfølsomhed <0.Slukket 1.Mindst følsom 9.Mest følsom"
},
"TemperatureUnit": {
"text": "TMPUNT",
"text2": [
"",
""
"Temperature",
"unit"
],
"desc": "Temperatur Enhed <C=Celsius F=Fahrenheit"
},
"AdvancedIdle": {
"text": "ADVIDL",
"text2": [
"",
""
"Detailed",
"idle screen"
],
"desc": "Vis detialieret information med en mindre skriftstørrelse på standby skærmen."
},
"DisplayRotation": {
"text": "DSPROT",
"text2": [
"",
""
"Display",
"orientation"
],
"desc": "Skærm Orientering <A. Automatisk V. Venstre Håndet H. Højre Håndet"
},
"BoostEnabled": {
"text": "BOOST",
"text2": [
"",
""
],
"desc": "Ved tryk på front knap Aktiveres boost-funktionen, 450C tilstand når der loddes"
},
"BoostTemperature": {
"text": "BTMP",
"text2": [
"",
""
"Boost",
"temp"
],
"desc": "Temperatur i \"boost\" mode"
},
"AutoStart": {
"text": "ASTART",
"text2": [
"",
""
"Auto",
"start"
],
"desc": "Start automatisk med lodning når strøm sættes til. L=Lodning, D= Dvale tilstand,S=Slukket"
},
"CooldownBlink": {
"text": "CLBLNK",
"text2": [
"",
""
"Cooldown",
"blink"
],
"desc": "Blink temperaturen på skærmen, mens spidsen stadig er varm."
},
"TemperatureCalibration": {
"text": "TMP CAL?",
"text2": [
"",
""
"Calibrate",
"temperature?"
],
"desc": "kalibrere spids temperatur."
},
"SettingsReset": {
"text": "RESET?",
"text2": [
"",
""
"Factory",
"Reset?"
],
"desc": "Gendan alle indstillinger"
},
"VoltageCalibration": {
"text": "CAL VIN?",
"text2": [
"",
""
"Calibrate",
"input voltage?"
],
"desc": "VIN kalibrering. Knapperne justere, Lang tryk for at gå ud"
},
"AdvancedSoldering": {
"text": "ADVSLD",
"text2": [
"",
""
"Detailed",
"solder screen"
],
"desc": "Vis detialieret information mens der loddes"
},
"ScrollingSpeed": {
"text": "DESCSP",
"text2": [
"",
""
"Scrolling",
"speed"
],
"desc": "Speed this text scrolls past at"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"Tip",
"Model"
@@ -211,7 +185,6 @@
"desc": "Tip Model selection"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"Simple",
"Calibration"
@@ -219,7 +192,6 @@
"desc": "Simple Calibration using Hot water"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"Advanced",
"Calibration"
@@ -227,23 +199,13 @@
"desc": "Advanced calibration using thermocouple on the tip"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"Power",
"Wattage"
],
"desc": "Power Wattage of the power adapter used"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"Power",
"Limit"
@@ -251,7 +213,6 @@
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"Key +-",
"reverse?"
@@ -259,7 +220,6 @@
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"Temp change",
"short?"
@@ -267,7 +227,6 @@
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"Temp change",
"long?"
@@ -275,7 +234,6 @@
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"Power",
"Pulse W"
@@ -283,7 +241,6 @@
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"Modify",
"tip gain"

View File

@@ -37,7 +37,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -70,200 +69,161 @@
},
"menuOptions": {
"PowerSource": {
"text": "PWRSC",
"text2": [
"text2": [
"Spannungs-",
"quelle"
],
"desc": "Spannungsquelle (Abschaltspannung) <DC=10V, nS=n*3.3V für n LiIon-Zellen>"
},
"SleepTemperature": {
"text": "STMP",
"text2": [
"text2": [
"Ruhetemp-",
"eratur"
],
"desc": "Ruhetemperatur"
},
"SleepTimeout": {
"text": "STME",
"text2": [
"text2": [
"Ruhever-",
"zögerung"
],
"desc": "Ruhemodus nach <Sekunden/Minuten>"
},
"ShutdownTimeout": {
"text": "SHTME",
"text2": [
"text2": [
"Abschalt-",
"zeit"
],
"desc": "Abschalten nach <Minuten>"
},
"MotionSensitivity": {
"text": "MSENSE",
"text2": [
"text2": [
"Bewegungs-",
"empfindlichk."
],
"desc": "Bewegungsempfindlichkeit <0=Aus, 1=Minimal ... 9=Maximal>"
},
"TemperatureUnit": {
"text": "TMPUNT",
"text2": [
"text2": [
"Temperatur-",
"einheit"
],
"desc": "Temperatureinheit <C=Celsius, F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "ADVIDL",
"text2": [
"text2": [
"Detaillierte",
"Ruheansicht"
],
"desc": "Detaillierte Anzeige im Ruhemodus"
},
"DisplayRotation": {
"text": "DSPROT",
"text2": [
"text2": [
"Anzeige-",
"ausrichtung"
],
"desc": "Ausrichtung der Anzeige <A=Automatisch, L=Linkshändig, R=Rechtshändig>"
},
"BoostEnabled": {
"text": "BOOST",
"text2": [
"Boosttaste",
"aktiv?"
],
"desc": "Vordere Taste lange drücken für Temperatur-Boostmodus beim Löten"
},
"BoostTemperature": {
"text": "BTMP",
"text2": [
"text2": [
"Boosttemp-",
"eratur"
],
"desc": "Temperatur im Boostmodus (In der eingestellten Einheit)"
},
"AutoStart": {
"text": "ASTART",
"text2": [
"text2": [
"Start im",
"Lötmodus?"
],
"desc": "Automatischer Start-Modus beim Einschalten der Spannungsversorgung. <T=Lötmodus S=Ruhezustand F=Aus>"
},
"CooldownBlink": {
"text": "CLBLNK",
"text2": [
"text2": [
"Abkühl-",
"blinken?"
],
"desc": "Blinkende Temperaturanzeige beim Abkühlen, solange heiß ist."
},
"TemperatureCalibration": {
"text": "TMP CAL?",
"text2": [
"text2": [
"Temperatur",
"kalibrieren?"
],
"desc": "Kalibrierung der Lötspitzentemperatur"
},
"SettingsReset": {
"text": "RESET?",
"text2": [
"text2": [
"Einstellungen",
"zurücksetzen?"
],
"desc": "Einstellungen auf werkseinstellungen zurück setzen"
},
"VoltageCalibration": {
"text": "CAL VIN?",
"text2": [
"text2": [
"Eingangsspannung",
"kalibrieren?"
],
"desc": "Kalibrierung der Eingangsspannung. Kurzer Tastendruck zum Einstellen, langer Tastendruck zum Verlassen."
},
"AdvancedSoldering": {
"text": "ADVSLD",
"text2": [
"text2": [
"Detaillierte",
"Lötansicht"
],
"desc": "Detaillierte Anzeige im Lötmodus"
},
"ScrollingSpeed": {
"text": "DESCSP",
"text2": [
"text2": [
"Scroll-",
"geschw."
],
"desc": "Scrollgeschwindigkeit der Texte <S=Langsam F=Schnell>"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Löt-",
"spitze"
],
"desc": "Auswahl der Lötspitze"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Einfache",
"Kalibrierung"
],
"desc": "Einfache Kalibrierung mittels heißem Wasser"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Erweiterte",
"Kalibrierung"
],
"desc": "Erweiterte Kalibrierung mittels eines Thermoelements an der Lötspitze"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Leistungs-",
"Aufnahme"
],
"desc": "Leistungsaufnahme der verwendeten Spannungsversorgung"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"Leistungs-",
"Limit An"
],
"desc": "Leistungslimit aktivieren"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Leistungs-",
"Limit"
],
"desc": "Maximale aufnahme der Lötspitze <Watt>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Taste +-",
"Umkehren?"
],
"desc": "Temperatur-Änderungs-Tasten-Belegung Plus-Minus umkehren?"
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"T. Schritt",
"Taste kurz?"
],
@@ -271,24 +231,21 @@
}
,
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"T. Schritt",
"Taste Lang?"
],
"desc": "Temperaturwechselschritte bei langem Tastendruck!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -37,7 +37,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -70,224 +69,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "PWRSC",
"text2": [
"text2": [
"Power",
"source"
],
"desc": "Power source. Sets cutoff voltage. <DC 10V> <S 3.3V per cell, disable power limit>"
},
"SleepTemperature": {
"text": "STMP",
"text2": [
"text2": [
"Sleep",
"temp"
],
"desc": "Sleep temperature"
},
"SleepTimeout": {
"text": "STME",
"text2": [
"text2": [
"Sleep",
"timeout"
],
"desc": "Sleep timeout <Minutes/Seconds>"
},
"ShutdownTimeout": {
"text": "SHTME",
"text2": [
"text2": [
"Shutdown",
"timeout"
],
"desc": "Shutdown timeout <Minutes>"
},
"MotionSensitivity": {
"text": "MSENSE",
"text2": [
"text2": [
"Motion",
"sensitivity"
],
"desc": "Motion sensitivity <0=Off 1=Least sensitive 9=Most sensitive>"
},
"TemperatureUnit": {
"text": "TMPUNT",
"text2": [
"text2": [
"Temperature",
"unit"
],
"desc": "Temperature unit <C=Celsius F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "ADVIDL",
"text2": [
"text2": [
"Detailed",
"idle screen"
],
"desc": "Display detailed information in a smaller font on the idle screen"
},
"DisplayRotation": {
"text": "DSPROT",
"text2": [
"text2": [
"Display",
"orientation"
],
"desc": "Display orientation <A=Automatic L=Left-handed R=Right-handed>"
},
"BoostEnabled": {
"text": "BOOST",
"text2": [
"Boost",
"mode"
],
"desc": "Enable front key long press \"boost mode\" when soldering"
},
"BoostTemperature": {
"text": "BTMP",
"text2": [
"text2": [
"Boost",
"temp"
],
"desc": "Temperature when in \"boost mode\""
},
"AutoStart": {
"text": "ASTART",
"text2": [
"text2": [
"Auto",
"start"
],
"desc": "Automatically starts the iron into soldering on power up <F=Off T=Soldering S=Sleep O=Sleep at room temperature>"
},
"CooldownBlink": {
"text": "CLBLNK",
"text2": [
"text2": [
"Cooldown",
"blink"
],
"desc": "Blink the temperature on the cooling screen while the tip is still hot"
},
"TemperatureCalibration": {
"text": "TMP CAL?",
"text2": [
"text2": [
"Calibrate",
"temperature?"
],
"desc": "Calibrate tip offset?"
},
"SettingsReset": {
"text": "RESET?",
"text2": [
"text2": [
"Factory",
"Reset?"
],
"desc": "Reset all settings!"
},
"VoltageCalibration": {
"text": "CAL VIN?",
"text2": [
"text2": [
"Calibrate",
"input voltage?"
],
"desc": "VIN Calibration <long press to exit>"
},
"AdvancedSoldering": {
"text": "ADVSLD",
"text2": [
"text2": [
"Detailed",
"solder screen"
],
"desc": "Display detailed information while soldering"
},
"ScrollingSpeed": {
"text": "DESCSP",
"text2": [
"text2": [
"Scrolling",
"speed"
],
"desc": "Speed this text scrolls past at <S=Slow F=Fast>"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Tip",
"model"
],
"desc": "Tip model selection"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Simple",
"calibration"
],
"desc": "Simple calibration using hot water"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Advanced",
"calibration"
],
"desc": "Advanced calibration using thermocouple on the tip"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Power",
"wattage"
],
"desc": "Power wattage of the power adapter used"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"Enable power",
"limit"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Reverse",
"+ - keys"
],
"desc": "Reverse assignment of temperature adjustment buttons"
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short"
],
"desc": "Temperature change steps on short button press"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long"
],
"desc": "Temperature change steps on long button press"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -23,7 +23,7 @@
"OffString": " No",
"ResetOKMessage": "Hecho. ",
"YourGainMessage": "Gananc.:",
"SettingsResetMessage": "Restablecidos."
"SettingsResetMessage": "Ajustes borrados"
},
"characters": {
"SettingRightChar": "D",
@@ -36,7 +36,6 @@
"SettingStartSleepOffChar": "F",
"SettingStartNoneChar": "N"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -69,228 +68,186 @@
},
"menuOptions": {
"PowerSource": {
"text": "PWRSC",
"text2": [
"text2": [
"Fuente",
"de energía"
],
"desc": "Elige el tipo de fuente para limitar el voltaje <DC 10V> <S 3,3V por pila, ilimitado>"
},
"SleepTemperature": {
"text": "STMP",
"text2": [
"text2": [
"Temperatura",
"en reposo"
],
"desc": "Temperatura de la punta en reposo."
},
"SleepTimeout": {
"text": "STME",
"text2": [
"text2": [
"Entrar",
"en reposo"
],
"desc": "Tiempo de inactividad para entrar en reposo <min/seg>"
},
"ShutdownTimeout": {
"text": "SHTME",
"text2": [
"text2": [
"Tiempo de",
"apagado"
],
"desc": "Tiempo de inactividad para apagarse <en minutos>"
},
"MotionSensitivity": {
"text": "MSENSE",
"text2": [
"text2": [
"Detección de",
"movimiento"
],
"desc": "Tiempo de reacción al agarrar <0=no 1=menos sensible 9=más sensible>"
},
"TemperatureUnit": {
"text": "TMPUNT",
"text2": [
"text2": [
"Unidad de",
"temperatura"
],
"desc": "Unidad de temperatura <C=centígrados F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "ADVIDL",
"text2": [
"text2": [
"Info extra en",
"modo reposo"
],
"desc": "Muestra información detallada en letra pequeña al reposar."
},
"DisplayRotation": {
"text": "DSPROT",
"text2": [
"text2": [
"Orientación",
"de pantalla"
],
"desc": "Orientación de la pantalla <A=automático I=zurdo D=diestro>"
},
"BoostEnabled": {
"text": "BOOST",
"text2": [
"Con botón de",
"temp. extra"
],
"desc": "Permite mantener pulsado el primer botón (A) al soldar y calentar momentáneamente un poco más."
},
"BoostTemperature": {
"text": "BTMP",
"text2": [
"text2": [
"Ajustar la",
"temp. extra"
],
"desc": "Temperatura momentánea que se alcanza al apretar el botón del modo extra."
},
"AutoStart": {
"text": "ASTART",
"text2": [
"text2": [
"Calentar",
"al enchufar"
],
"desc": "Se calienta él solo al arrancar <S=entrar en modo soldar R=solo entrar en reposo F=en reposo pero mantiene la punta fría N=no>"
},
"CooldownBlink": {
"text": "CLBLNK",
"text2": [
"text2": [
"Parpadear",
"al enfriar"
],
"desc": "La temperatura en pantalla parpadea mientras la punta siga caliente."
},
"TemperatureCalibration": {
"text": "TMP CAL?",
"text2": [
"text2": [
"Calibrar temp.",
"de la punta"
],
"desc": "Calibra la desviación térmica de la punta."
},
"SettingsReset": {
"text": "RESET?",
"text2": [
"text2": [
"Volver a ajustes",
"de fábrica"
],
"desc": "Restablece todos los ajustes a los valores originales."
},
"VoltageCalibration": {
"text": "CAL VIN?",
"text2": [
"text2": [
"Calibrar voltaje",
"de entrada"
],
"desc": "Calibra VIN. Ajusta con ambos botones y mantén pulsado para salir."
},
"AdvancedSoldering": {
"text": "ADVSLD",
"text2": [
"text2": [
"Info extra",
"al soldar"
],
"desc": "Muestra más datos por pantalla cuando se está soldando."
},
"ScrollingSpeed": {
"text": "DESCSP",
"text2": [
"text2": [
"Velocidad",
"del texto"
],
"desc": "Velocidad de desplazamiento del texto <R=rápida L=lenta>"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Modelo de",
"punta"
],
"desc": "Elegir el modelo de punta actual."
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Calibración",
"simple"
],
"desc": "Calibración simple con agua caliente."
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Calibración",
"avanzada"
],
"desc": "Calibrar con un termopar en la punta; más difícil."
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Potencia de",
"entrada"
],
"desc": "Potencia en vatios del adaptador de corriente utilizado."
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"Limitar la",
"potenc. máx."
],
"desc": "Activa el límite de potencia máxima."
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Ajustar la",
"potenc. máx."
],
"desc": "Elige el límite de potencia máxima del soldador <en vatios>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"Key +-",
"reverse?"
"text2": [
"Invertir",
"botones +/-"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
"desc": "Intercambia las funciones de subir y bajar la temperatura de los botones +/- para que funcionen al revés."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"Temp change",
"short?"
"text2": [
"Cambio temp.",
"puls. cortas"
],
"desc": "Temperature change steps on short button press!"
"desc": "Subir y bajar X grados de temperatura con cada pulsación corta de los botones +/-."
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"Temp change",
"long?"
"text2": [
"Cambio temp.",
"puls. largas"
],
"desc": "Temperature change steps on long button press!"
"desc": "Subir y bajar X grados de temperatura con cada pulsación larga de los botones +/-."
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"Power",
"Pulse W"
"PowerPulsePower": {
"text2": [
"Pulsos bat.",
"constantes"
],
"desc": "Keep awake pulse power intensity"
"desc": "Aplica unos pulsos necesarios para mantener encendidas ciertas baterías portátiles. En vatios."
},
"TipGain": {
"text": "TG",
"text2": [
"Modify",
"tip gain"
"text2": [
"Ajustar ganancia",
"de punta"
],
"desc": "Tip gain"
"desc": "Modificar el valor de ganancia de la punta."
}
}
}
}

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "",
"text2": [
"text2": [
"Virtalähde",
"DC"
],
"desc": "Käytettävä virtalähde. Asettaa katkaisujänniteen. <DC 10V, 3S=9.9V, 4S=13.2V, 5S=16.5V, 6S=19.8V>"
},
"SleepTemperature": {
"text": "",
"text2": [
"text2": [
"Lepotilan",
"lämpötila"
],
"desc": "Lepotilan lämpötila. <C>"
},
"SleepTimeout": {
"text": "",
"text2": [
"text2": [
"Lepotilan",
"viive"
],
"desc": "Lepotilan viive. <minuuttia/sekuntia>"
},
"ShutdownTimeout": {
"text": "",
"text2": [
"text2": [
"Sammutus",
"viive"
],
"desc": "Automaattisen sammutuksen aikaviive. <minuuttia>"
},
"MotionSensitivity": {
"text": "",
"text2": [
"text2": [
"Liikkeen",
"herkkyys"
],
"desc": "Liikkeentunnistuksen herkkyys. <0=pois, 1=epäherkin, 9=herkin>"
},
"TemperatureUnit": {
"text": "",
"text2": [
"text2": [
"Lämpötilan",
"yksikkö"
],
"desc": "Lämpötilan yksikkö. <C=celsius, F=fahrenheit>"
},
"AdvancedIdle": {
"text": "",
"text2": [
"text2": [
"Tiedot",
"lepotilassa"
],
"desc": "Näyttää yksityiskohtaisemmat tiedot lepotilassa."
},
"DisplayRotation": {
"text": "",
"text2": [
"text2": [
"Näytön",
"kierto"
],
"desc": "Näytön kierto. <A=automaattinen O=oikeakätinen V=vasenkätinen>"
},
"BoostEnabled": {
"text": "",
"text2": [
"Tehostus",
"käytössä"
],
"desc": "Etupainikeella siirrytään juotettaessa tehostustilaan."
},
"BoostTemperature": {
"text": "",
"text2": [
"text2": [
"Tehostus-",
"lämpötila"
],
"desc": "Tehostustilan lämpötila"
},
"AutoStart": {
"text": "",
"text2": [
"text2": [
"Autom.",
"käynnistys"
],
"desc": "Käynnistää virrat kytkettäessä juotostilan automaattisesti. T=juotostila, S=Lepotila, F=Ei käytössä"
},
"CooldownBlink": {
"text": "",
"text2": [
"text2": [
"Jäähdytyksen",
"vilkutus"
],
"desc": "Vilkuttaa jäähtyessä juotoskärjen lämpötilaa sen ollessa vielä vaarallisen kuuma."
},
"TemperatureCalibration": {
"text": "",
"text2": [
"text2": [
"Kalibroi",
"lämpötila?"
],
"desc": "Kalibroi kärjen lämpötilaeron."
},
"SettingsReset": {
"text": "",
"text2": [
"text2": [
"Palauta",
"tehdasasetukset?"
],
"desc": "Palauta kaikki asetukset oletusarvoihin."
},
"VoltageCalibration": {
"text": "",
"text2": [
"text2": [
"Kalibroi",
"tulojännite?"
],
"desc": "Tulojännitten kalibrointi (VIN). Painikkeilla säädetään ja pitkään painamalla poistutaan."
},
"AdvancedSoldering": {
"text": "",
"text2": [
"text2": [
"Tarkempi",
"juotosnäyttö"
],
"desc": "Näyttää yksityiskohtaisemmat tiedot juotostilassa."
},
"ScrollingSpeed": {
"text": "",
"text2": [
"text2": [
"Tietojen",
"näyttönopeus"
],
"desc": "Näiden selitetekstien vieritysnopeus."
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Tip",
"Model"
],
"desc": "Tip Model selection"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Simple",
"Calibration"
],
"desc": "Simple Calibration using Hot water"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Advanced",
"Calibration"
],
"desc": "Advanced calibration using thermocouple on the tip"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Power",
"Wattage"
],
"desc": "Power Wattage of the power adapter used"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "D"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "",
"text2": [
"text2": [
"Source",
"d'alim"
],
"desc": "Source d'alimentation. Règle la tension de coupure <DC=10V S=3.3V par cellules>"
},
"SleepTemperature": {
"text": "",
"text2": [
"text2": [
"Temp.",
"veille"
],
"desc": "Température en veille <C>"
},
"SleepTimeout": {
"text": "",
"text2": [
"text2": [
"Délai",
"veille"
],
"desc": "Délai avant mise en veille <Minutes>"
},
"ShutdownTimeout": {
"text": "",
"text2": [
"text2": [
"Délai",
"extinction"
],
"desc": "Délai avant extinction <Minutes>"
},
"MotionSensitivity": {
"text": "",
"text2": [
"text2": [
"Sensibilité",
"au mouvement"
],
"desc": "Sensibilité du capteur de mouvement <0=Inactif 1=Peu sensible 9=Tres sensible>"
},
"TemperatureUnit": {
"text": "",
"text2": [
"text2": [
"Unité de",
"température"
],
"desc": "Unité de température <C=Celsius F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "",
"text2": [
"text2": [
"Écran veille",
"détaillé"
],
"desc": "Afficher des informations détaillées lors de la veille."
},
"DisplayRotation": {
"text": "",
"text2": [
"text2": [
"Orientation",
"de l'écran"
],
"desc": "Orientation de l'affichage <A=Automatique G=Gaucher D=Droitier>"
},
"BoostEnabled": {
"text": "",
"text2": [
"Activation du",
"mode Boost"
],
"desc": "Activer le mode \"Boost\" en maintenant le bouton de devant pendant la soudure"
},
"BoostTemperature": {
"text": "",
"text2": [
"text2": [
"Temp.",
"Boost"
],
"desc": "Température du mode \"Boost\""
},
"AutoStart": {
"text": "",
"text2": [
"text2": [
"Démarrage",
"automatique"
],
"desc": "Démarrer automatiquement la soudure a l'allumage <A=Activé, V=Mode Veille, D=Désactivé>"
},
"CooldownBlink": {
"text": "",
"text2": [
"text2": [
"Refroidir en",
"clignotant"
],
"desc": "Faire clignoter la température lors du refroidissement tant que la panne est chaude."
},
"TemperatureCalibration": {
"text": "",
"text2": [
"text2": [
"Étalonner",
"température"
],
"desc": "Étalonner température de la panne."
},
"SettingsReset": {
"text": "",
"text2": [
"text2": [
"Réinitialisation",
"d'usine"
],
"desc": "Réinitialiser tous les réglages"
},
"VoltageCalibration": {
"text": "",
"text2": [
"text2": [
"Étalonner",
"tension d'entrée"
],
"desc": "Étalonner tension d'entrée. Boutons pour ajuster, appui long pour quitter"
},
"AdvancedSoldering": {
"text": "",
"text2": [
"text2": [
"Écran soudure",
"détaillé"
],
"desc": "Afficher des informations détaillées pendant la soudure"
},
"ScrollingSpeed": {
"text": "",
"text2": [
"text2": [
"Vitesse de",
"défilement"
],
"desc": "Vitesse de défilement de ce texte en <R=Rapide L=Lent>"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Panne",
"Modèle"
],
"desc": "Sélection du modèle de la panne"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Calibration",
"simple"
],
"desc": "Calibration simple à l'aide d'eau chaude"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Calibration",
"avancées"
],
"desc": "Calibration avancées à l'aide d'un thermocouple sur la panne"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Puissance de",
"l'alimentation"
],
"desc": "Puissance de l'alimentation utilisée"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Activer?"
],
"desc": "Activer la limite de puissance"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Puissance",
"Limite"
],
"desc": "Puissance maximale utilisable <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"Inverser?"
],
"desc": "Inversez l'assignation +/- du bouton de changement de température de la pointe."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"Court?"
],
"desc": "Incrément de changement de température sur appui court."
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"Long?"
],
"desc": "Incrément de changement de température sur appui long."
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "PWRSC",
"text2": [
"text2": [
"Izvor",
"napajanja"
],
"desc": "Izvor napajanja. Postavlja napon isključivanja. <DC 10V> <S 3.3V po ćeliji>"
},
"SleepTemperature": {
"text": "STMP",
"text2": [
"text2": [
"Temp",
"spavanja"
],
"desc": "Temperatura na koju se spušta lemilica nakon određenog vremena mirovanja. <C/F>"
},
"SleepTimeout": {
"text": "STME",
"text2": [
"text2": [
"Vrijeme",
"spavanja"
],
"desc": "Vrijeme mirovanja nakon kojega lemilica spušta temperaturu. <Minute/Sekunde>"
},
"ShutdownTimeout": {
"text": "SHTME",
"text2": [
"text2": [
"Vrijeme",
"gašenja"
],
"desc": "Vrijeme mirovanja nakon kojega će se lemilica ugasiti. <Minute>"
},
"MotionSensitivity": {
"text": "MSENSE",
"text2": [
"text2": [
"Osjetljivost",
"pokreta"
],
"desc": "Osjetljivost prepoznavanja pokreta. <0=Ugašeno, 1=Najmanje osjetljivo, 9=Najosjetljivije>"
},
"TemperatureUnit": {
"text": "TMPUNT",
"text2": [
"text2": [
"Jedinica",
"temperature"
],
"desc": "Jedinica temperature. <C=Celzij, F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "ADVIDL",
"text2": [
"text2": [
"Detalji",
"pri čekanju"
],
"desc": "Prikazivanje detaljnih informacija tijekom čekanja."
},
"DisplayRotation": {
"text": "DSPROT",
"text2": [
"text2": [
"Rotacija",
"ekrana"
],
"desc": "Orijentacija ekrana. <A=Automatski, L=Ljevoruki, D=Desnoruki>"
},
"BoostEnabled": {
"text": "BOOST",
"text2": [
"Boost",
"način"
],
"desc": "Držanjem prednjeg gumba prilikom lemljenja aktivira se pojačani (Boost) način."
},
"BoostTemperature": {
"text": "BTMP",
"text2": [
"text2": [
"Boost",
"temp"
],
"desc": "Temperatura u pojačanom (Boost) načinu."
},
"AutoStart": {
"text": "ASTART",
"text2": [
"text2": [
"Auto",
"start"
],
"desc": "Ako je aktivno, lemilica po uključivanju napajanja odmah počinje grijati."
},
"CooldownBlink": {
"text": "CLBLNK",
"text2": [
"text2": [
"Upozorenje",
"pri hlađenju"
],
"desc": "Bljeskanje temperature prilikom hlađenja, ako je lemilica vruća."
},
"TemperatureCalibration": {
"text": "TMP CAL?",
"text2": [
"text2": [
"Kalibracija",
"temperature"
],
"desc": "Kalibriranje temperature mjeri razliku temperatura vrška i drške, dok je lemilica hladna."
},
"SettingsReset": {
"text": "RESET?",
"text2": [
"text2": [
"Tvorničke",
"postavke"
],
"desc": "Vraćanje svih postavki na tvorničke vrijednosti."
},
"VoltageCalibration": {
"text": "CAL VIN?",
"text2": [
"text2": [
"Kalibracija",
"napona napajanja"
],
"desc": "Kalibracija ulaznog napona. Podešavanje gumbima, dugački pritisak za kraj."
},
"AdvancedSoldering": {
"text": "ADVSLD",
"text2": [
"text2": [
"Detalji",
"pri lemljenju"
],
"desc": "Prikazivanje detaljnih informacija tijekom lemljenja."
},
"ScrollingSpeed": {
"text": "DESCSP",
"text2": [
"text2": [
"Brzina",
"poruka"
],
"desc": "Brzina kretanja dugačkih poruka. <B=brzo, S=sporo>"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Model",
"Vrha"
],
"desc": "Odabir modela lemnog vrha"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Jednostavna",
"kalibracija"
],
"desc": "Kalibracija kipućom vodom"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Napredna",
"kalibracija"
],
"desc": "Kalibracija korištenjem termo-elementa"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Snaga",
"napajanja"
],
"desc": "Snaga modula za napajanje"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": false,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "ÁRAMF",
"text2": [
"text2": [
"Áram",
"forrás"
],
"desc": "Áramforrás. Beállítja a lekapcsolási feszültséget. <DC 10V> <S 3.3V cellánként>"
},
"SleepTemperature": {
"text": "AHŐM",
"text2": [
"text2": [
"Alvási",
"hőfok"
],
"desc": "Alvási hőmérséklet <C>"
},
"SleepTimeout": {
"text": "AIDŐ",
"text2": [
"text2": [
"Alvás",
"időzítő"
],
"desc": "Alvás időzítő <perc/másodperc>"
},
"ShutdownTimeout": {
"text": "KIIDŐ",
"text2": [
"text2": [
"Kikapcsolás",
"időzítő"
],
"desc": "Kikapcsolási időzítő <perc>"
},
"MotionSensitivity": {
"text": "MOZGÉR",
"text2": [
"text2": [
"Mozgás",
"érzékenység"
],
"desc": "Mozgás érzékenység beállítása. <0.kikapcsolva 1.legkevésbé érzékeny 9.legérzékenyebb>"
},
"TemperatureUnit": {
"text": "HŐEGYS",
"text2": [
"text2": [
"Hőmérséklet",
"mértékegysége"
],
"desc": "Hőmérséklet mértékegysége <C=Celsius F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "RÉSZLI",
"text2": [
"text2": [
"Részletes",
"készenlét"
],
"desc": "Részletes információ megjelenítése kisebb betűméretben a készenléti képernyőn."
},
"DisplayRotation": {
"text": "KIJTÁJ",
"text2": [
"text2": [
"Kijelző",
"tájolása"
],
"desc": "Kijelző tájolása <A. automatikus B. balkezes J. jobbkezes>"
},
"BoostEnabled": {
"text": "BOOST",
"text2": [
"Boost",
"mód"
],
"desc": "Elülső gombbal boost módba (450C) lép forrasztás közben"
},
"BoostTemperature": {
"text": "BHŐ",
"text2": [
"text2": [
"Boost",
"hőfok"
],
"desc": "Hőmérséklet \"boost\" módban"
},
"AutoStart": {
"text": "ASTART",
"text2": [
"text2": [
"Automatikus",
"indítás"
],
"desc": "Bekapcsolás után automatikusan lépjen forrasztás módba. T=forrasztás, S=alvó mód, F=ki"
},
"CooldownBlink": {
"text": "HŰLÉSV",
"text2": [
"text2": [
"Villogás",
"hűléskor"
],
"desc": "Villogjon a hőmérséklet hűlés közben, amíg a hegy forró."
},
"TemperatureCalibration": {
"text": "HŐM KAL?",
"text2": [
"text2": [
"Hőmérséklet",
"kalibrálása?"
],
"desc": "Hegy hőmérséklet-különbségének kalibrálása."
},
"SettingsReset": {
"text": "RESET?",
"text2": [
"text2": [
"Gyári",
"beállítások?"
],
"desc": "Beállítások alaphelyzetbe állítása"
},
"VoltageCalibration": {
"text": "VIN KAL?",
"text2": [
"text2": [
"Bemeneti fesz",
"kalibrálása?"
],
"desc": "Bemeneti feszültség kalibrálása. Röviden megnyomva módosítás, hosszan megnyomva kilépés"
},
"AdvancedSoldering": {
"text": "HALKÉP",
"text2": [
"text2": [
"Részletes",
"forr. kép."
],
"desc": "Részletes információk megjelenítése forrasztás közben"
},
"ScrollingSpeed": {
"text": "GÖRGS",
"text2": [
"text2": [
"Görgetés",
"sebessége"
],
"desc": "Szöveggörgetés sebessége"
},
"TipModel": {
"text": "HEGYMOD",
"text2": [
"text2": [
"Forrasztóhegy",
"modell"
],
"desc": "Forrasztóhegy modell kiválasztása"
},
"SimpleCalibrationMode": {
"text": "EGYSZKAL",
"text2": [
"text2": [
"Egyszerű",
"kalibráció"
],
"desc": "Egyszerű kalibrálás forró víz segítségével"
},
"AdvancedCalibrationMode": {
"text": "HALKAL",
"text2": [
"text2": [
"Haladó",
"Kalibráció"
],
"desc": "Haladó kalibrálás hegyre helyezett hőelem segítségével"
},
"PowerInput": {
"text": "TELJW",
"text2": [
"text2": [
"Bemeneti",
"teljesítmény"
],
"desc": "A tápegység által leadott teljesítmény"
},
"PowerLimitEnable": {
"text": "TELJH",
"text2": [
"Telj H",
"Bekapcsolva"
],
"desc": "Bemeneti teljesitmény korlátozása"
},
"PowerLimit": {
"text": "TELJM",
"text2": [
"text2": [
"Telj",
"maximum"
],
"desc": "Maximális teljesitmény beállitása <Watts>"
},
"ReverseButtonTempChange": {
"text": "HÖVÁLT",
"text2": [
"text2": [
"GOMB +-",
"Felcseréled?"
],
"desc": "A páka hömérséklet növelés csökkentési gombok felcserélése."
},
"TempChangeShortStep": {
"text": "HÖRÖV",
"text2": [
"text2": [
"Hömérséklet",
"váltás rövid?"
],
"desc": "Hömérséklet váltás rövid gombnyomásrs bekapcsolva!"
},
"TempChangeLongStep": {
"text": "HÖHOS",
"text2": [
"text2": [
"Hömérséklet",
"váltás hosszú?"
],
"desc": "Hömérséklet váltás hosszú gombnyomásrs bekapcsolva!"
},
"PowerPulsePower":{
"text": "TELJP",
"text2": [
"text2": [
"Telj power",
"bank üzem W"
],
"desc": "Powerbank üzemnél nem engedi a powerbankot kikapcsolni idönkénti áram felvételt generál. "
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -36,7 +36,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "D"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -69,228 +68,186 @@
},
"menuOptions": {
"PowerSource": {
"text": "",
"text2": [
"text2": [
"Sorgente",
"alimentaz"
],
"desc": "Scegli la sorgente di alimentazione; se a batteria, limita lo scaricamento al valore di soglia <DC: 10V; S: 3,3V per cella>"
},
"SleepTemperature": {
"text": "",
"text2": [
"text2": [
"Temp",
"standby"
],
"desc": "Imposta la temperatura da mantenere in modalità Standby <°C/°F>"
},
"SleepTimeout": {
"text": "",
"text2": [
"text2": [
"Timer",
"standby"
],
"desc": "Imposta il timer per entrare in modalità Standby <minuti/secondi>"
},
"ShutdownTimeout": {
"text": "",
"text2": [
"text2": [
"Timer",
"spegnimento"
],
"desc": "Imposta il timer per lo spegnimento <minuti>"
},
"MotionSensitivity": {
"text": "",
"text2": [
"text2": [
"Sensibilità",
"al movimento"
],
"desc": "Imposta la sensibilità al movimento per uscire dalla modalità Standby <0: nessuna; 1: minima; 9: massima>"
},
"TemperatureUnit": {
"text": "",
"text2": [
"text2": [
"Unità di",
"temperatura"
],
"desc": "Scegli l'unità di misura per la temperatura <C: grado Celsius; F: grado Farenheit>"
},
"AdvancedIdle": {
"text": "",
"text2": [
"text2": [
"Interfaccia",
"testuale"
],
"desc": "Mostra informazioni dettagliate all'interno della schermata principale"
},
"DisplayRotation": {
"text": "",
"text2": [
"text2": [
"Orientamento",
"display"
],
"desc": "Imposta l'orientamento del display <A: automatico; S: mano sinistra; D: mano destra>"
},
"BoostEnabled": {
"text": "",
"text2": [
"Funzione",
"«Turbo»"
],
"desc": "Attiva la funzione «Turbo», durante la modalità Saldatura, tenendo premuto il tasto superiore"
},
"BoostTemperature": {
"text": "",
"text2": [
"text2": [
"Temp",
"«Turbo»"
],
"desc": "Imposta la temperatura della funzione «Turbo»"
},
"AutoStart": {
"text": "",
"text2": [
"text2": [
"Avvio",
"automatico"
],
"desc": "Attiva automaticamente il saldatore quando viene alimentato <A: saldatura; S: standby; D: disattiva>"
},
"CooldownBlink": {
"text": "",
"text2": [
"text2": [
"Avviso",
"punta calda"
],
"desc": "Evidenzia il valore di temperatura durante il raffreddamento se la punta è ancora calda"
},
"TemperatureCalibration": {
"text": "",
"text2": [
"text2": [
"Calibrazione",
"temperatura"
],
"desc": "Calibra le rilevazioni di temperatura"
},
"SettingsReset": {
"text": "",
"text2": [
"text2": [
"Ripristino",
"impostazioni"
],
"desc": "Ripristina tutte le impostazioni"
},
"VoltageCalibration": {
"text": "",
"text2": [
"text2": [
"Calibrazione",
"tensione"
],
"desc": "Calibra la tensione in ingresso; regola con entrambi i tasti, tieni premuto il tasto superiore per uscire"
},
"AdvancedSoldering": {
"text": "",
"text2": [
"text2": [
"Dettagli",
"saldatura"
],
"desc": "Mostra informazioni dettagliate durante la modalità Saldatura"
},
"ScrollingSpeed": {
"text": "",
"text2": [
"text2": [
"Velocità",
"testo"
],
"desc": "Imposta la velocità di scorrimento del testo <L: lento; V: veloce>"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Modello",
"punta"
],
"desc": "Seleziona il modello della punta in uso"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Calibrazione",
"semplice"
],
"desc": "Calibra le rilevazioni di temperatura tramite l'utilizzo di acqua calda"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Calibrazione",
"avanzata"
],
"desc": "Calibra le rilevazioni di temperatura attraverso la termocoppia presente nella punta"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Potenza",
"alimentaz"
],
"desc": "Imposta la potenza massima erogabile dall'alimentatore in uso"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"Limitatore",
"di potenza"
],
"desc": "Abilita un limitatore per la potenza massima erogabile al saldatore"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Limite",
"di potenza"
],
"desc": "Imposta il valore di potenza massima erogabile al saldatore <watt>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Inversione",
"tasti"
],
"desc": "Inverti i tasti per impostare la temperatura della punta "
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Cambio temp",
"pressione breve"
],
"desc": "Varia la temperatura della punta attraverso una breve pressione dei tasti"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Cambio temp",
"pressione lunga"
],
"desc": "Varia la temperatura della punta attraverso una lunga pressione dei tasti"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"Power",
"Pulse W"
"PowerPulsePower": {
"text2": [
"Potenza impulso",
"«Keep-Alive»"
],
"desc": "Keep awake pulse power intensity"
"desc": "Regola la potenza d'impulso in ingresso al saldatore per prevenire lo standby eventuale dell'alimentatore <watt>"
},
"TipGain": {
"text": "TG",
"text2": [
"Modify",
"tip gain"
"text2": [
"Guadagno",
"punta"
],
"desc": "Tip gain"
"desc": "Varia il guadagno della punta"
}
}
}

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "",
"text2": [
"text2": [
"Maitinimo",
"šaltinis"
],
"desc": "Išjungimo įtampa. <DC 10V arba celių (S) kiekis (3.3V per celę)>"
},
"SleepTemperature": {
"text": "",
"text2": [
"text2": [
"Miego",
"temperat."
],
"desc": "Miego temperatūra <C>"
},
"SleepTimeout": {
"text": "",
"text2": [
"text2": [
"Miego",
"laikas"
],
"desc": "Miego laikas <minutės/sekundės>"
},
"ShutdownTimeout": {
"text": "",
"text2": [
"text2": [
"Išjungimo",
"laikas"
],
"desc": "Išjungimo laikas <minutės>"
},
"MotionSensitivity": {
"text": "",
"text2": [
"text2": [
"Jautrumas",
"judesiui"
],
"desc": "Jautrumas judesiui <0 - išjungta, 1 - mažiausias, 9 - didžiausias>"
},
"TemperatureUnit": {
"text": "",
"text2": [
"text2": [
"Temperatūros",
"vienetai"
],
"desc": "Temperatūros vienetai <C - Celsijus, F - Farenheitas>"
},
"AdvancedIdle": {
"text": "",
"text2": [
"text2": [
"Detalus lauki",
"mo ekranas"
],
"desc": "Ar rodyti papildomą informaciją mažesniu šriftu laukimo ekrane"
},
"DisplayRotation": {
"text": "",
"text2": [
"text2": [
"Ekrano",
"orientacija"
],
"desc": "Ekrano orientacija <A - automatinė, K - kairiarankiams, D - dešiniarankiams>"
},
"BoostEnabled": {
"text": "",
"text2": [
"Turbo režimas",
"įjungtas"
],
"desc": "Ar lituojant viršutinis mygtukas įjungia turbo režimą"
},
"BoostTemperature": {
"text": "",
"text2": [
"text2": [
"Turbo",
"temperat."
],
"desc": "Temperatūra turbo režimu"
},
"AutoStart": {
"text": "",
"text2": [
"text2": [
"Auto",
"paleidimas"
],
"desc": "Ar pradėti kaitininti iš karto įjungus lituoklį"
},
"CooldownBlink": {
"text": "",
"text2": [
"text2": [
"Atvėsimo",
"mirksėjimas"
],
"desc": "Ar mirksėti temperatūrą ekrane kol vėstantis antgalis vis dar karštas"
},
"TemperatureCalibration": {
"text": "",
"text2": [
"text2": [
"Kalibruoti",
"temperatūrą?"
],
"desc": "Antgalio temperatūros kalibravimas"
},
"SettingsReset": {
"text": "",
"text2": [
"text2": [
"Atstatyti",
"nustatymus?"
],
"desc": "Nustatyti nustatymus iš naujo"
},
"VoltageCalibration": {
"text": "",
"text2": [
"text2": [
"Kalibruoti",
"įvesties įtampą?"
],
"desc": "Įvesties įtampos kalibravimas. Trumpai paspauskite, norėdami nustatyti, ilgai paspauskite, kad išeitumėte"
},
"AdvancedSoldering": {
"text": "",
"text2": [
"text2": [
"Detalus lita-",
"vimo ekranas"
],
"desc": "Ar rodyti išsamią informaciją lituojant"
},
"ScrollingSpeed": {
"text": "",
"text2": [
"text2": [
"Greitas apr",
"ašym. slink"
],
"desc": "Greitis, kuriuo šis tekstas slenka"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Antgalio",
"modelis"
],
"desc": "Antgalio modelio pasirinkimas"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Paprasta",
"kalibracija"
],
"desc": "Paprasta kalibracija naudojant karštą vandienį"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Išplėstinė",
"kalibracija"
],
"desc": "Išplėstinė kalibracija naudojant termoelementą"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Galia",
"vatais"
],
"desc": "Maitinimo bloko galia vatais"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "",
"text2": [
"text2": [
"Spannings-",
"bron"
],
"desc": "Spanningsbron. Stelt drempelspanning in. <DC 10V> <S 3.3V per cel>"
},
"SleepTemperature": {
"text": "",
"text2": [
"text2": [
"Slaap",
"temp"
],
"desc": "Temperatuur in slaapstand <C>"
},
"SleepTimeout": {
"text": "",
"text2": [
"text2": [
"Slaap",
"time-out"
],
"desc": "Slaapstand time-out <Minuten/Seconden>"
},
"ShutdownTimeout": {
"text": "",
"text2": [
"text2": [
"Uitschakel",
"time-out"
],
"desc": "Automatisch afsluiten time-out <Minuten>"
},
"MotionSensitivity": {
"text": "",
"text2": [
"text2": [
"Bewegings-",
"gevoeligheid"
],
"desc": "Bewegingsgevoeligheid <0.uit 1.minst gevoelig 9.meest gevoelig>"
},
"TemperatureUnit": {
"text": "",
"text2": [
"text2": [
"Temperatuur",
"eenheid"
],
"desc": "Temperatuureenheid <C=Celsius F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "",
"text2": [
"text2": [
"Gedetailleerd",
"slaapscherm"
],
"desc": "Gedetailleerde informatie weergeven in een kleiner lettertype op het slaapscherm."
},
"DisplayRotation": {
"text": "",
"text2": [
"text2": [
"Scherm-",
"oriëntatie"
],
"desc": "Schermoriëntatie <A. Automatisch L. Linkshandig R. Rechtshandig>"
},
"BoostEnabled": {
"text": "",
"text2": [
"Boostmodes",
"ingeschakeld?"
],
"desc": "Soldeerbout gaat naar een hogere boost-temperatuur wanneer de voorste knop ingedrukt is."
},
"BoostTemperature": {
"text": "",
"text2": [
"text2": [
"Boost",
"temp"
],
"desc": "Temperatuur in boostmodes"
},
"AutoStart": {
"text": "",
"text2": [
"text2": [
"Auto",
"start"
],
"desc": "Breng de soldeerbout direct op temperatuur bij het opstarten. T=Soldeertemperatuur, S=Slaapstand-temperatuur, F=Uit"
},
"CooldownBlink": {
"text": "",
"text2": [
"text2": [
"Afkoel",
"flikker"
],
"desc": "Temperatuur laten flikkeren in het hoofdmenu als de soldeerpunt aan het afkoelen is."
},
"TemperatureCalibration": {
"text": "",
"text2": [
"text2": [
"Calibreer",
"temperatuur?"
],
"desc": "Temperatuursafwijking van de soldeerpunt calibreren."
},
"SettingsReset": {
"text": "",
"text2": [
"text2": [
"Instellingen",
"resetten?"
],
"desc": "Alle instellingen terugzetten."
},
"VoltageCalibration": {
"text": "",
"text2": [
"text2": [
"Calibreer",
"input-voltage?"
],
"desc": "VIN Calibreren. Knoppen lang ingedrukt houden om te bevestigen."
},
"AdvancedSoldering": {
"text": "",
"text2": [
"text2": [
"Gedetailleerd",
"soldeerscherm"
],
"desc": "Gedetailleerde informatie weergeven in een kleiner lettertype op het soldeerscherm."
},
"ScrollingSpeed": {
"text": "",
"text2": [
"text2": [
"Scroll",
"snelheid"
],
"desc": "Snelheid waarmee de tekst scrolt."
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Tip",
"Model"
],
"desc": "Tip Model selection"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Simple",
"Calibration"
],
"desc": "Simple Calibration using Hot water"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Advanced",
"Calibration"
],
"desc": "Advanced calibration using thermocouple on the tip"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Power",
"Wattage"
],
"desc": "Power Wattage of the power adapter used"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "",
"text2": [
"text2": [
"Spannings-",
"bron"
],
"desc": "Spanningsbron. Stelt minimumspanning in. <DC 10V> <S 3.3V per cel>"
},
"SleepTemperature": {
"text": "",
"text2": [
"text2": [
"Slaap",
"temp"
],
"desc": "Temperatuur in slaapstand <°C>"
},
"SleepTimeout": {
"text": "",
"text2": [
"text2": [
"Slaap",
"time-out"
],
"desc": "Slaapstand time-out <Minuten/Seconden>"
},
"ShutdownTimeout": {
"text": "",
"text2": [
"text2": [
"Uitschakel",
"time-out"
],
"desc": "Automatisch afsluiten time-out <Minuten>"
},
"MotionSensitivity": {
"text": "",
"text2": [
"text2": [
"Bewegings-",
"gevoeligheid"
],
"desc": "Bewegingsgevoeligheid <0.uit 1.minst gevoelig 9.meest gevoelig>"
},
"TemperatureUnit": {
"text": "",
"text2": [
"text2": [
"Temperatuur",
"schaal"
],
"desc": "Temperatuurschaal <°C=Celsius °F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "",
"text2": [
"text2": [
"Gedetailleerd",
"slaapscherm"
],
"desc": "Gedetailleerde informatie in een kleiner lettertype in het slaapscherm."
},
"DisplayRotation": {
"text": "",
"text2": [
"text2": [
"Scherm-",
"oriëntatie"
],
"desc": "Schermoriëntatie <A. Automatisch L. Linkshandig R. Rechtshandig>"
},
"BoostEnabled": {
"text": "",
"text2": [
"Temperatuurverhoging",
"ingeschakeld?"
],
"desc": "Temperatuur verhoogt als voorste knop is ingedrukt"
},
"BoostTemperature": {
"text": "",
"text2": [
"text2": [
"Verhogings",
"temp"
],
"desc": "Verhogingstemperatuur"
},
"AutoStart": {
"text": "",
"text2": [
"text2": [
"Auto",
"start"
],
"desc": "Breng de soldeerbout op temperatuur bij het opstarten. T=Soldeertemperatuur, S=Slaapstand-temperatuur, F=Uit"
},
"CooldownBlink": {
"text": "",
"text2": [
"text2": [
"Afkoel",
"knipper"
],
"desc": "Temperatuur knippert in hoofdmenu tijdens afkoeling."
},
"TemperatureCalibration": {
"text": "",
"text2": [
"text2": [
"Calibreer",
"temperatuur?"
],
"desc": "Temperatuur van de punt calibreren."
},
"SettingsReset": {
"text": "",
"text2": [
"text2": [
"Instellingen",
"resetten?"
],
"desc": "Alle instellingen resetten."
},
"VoltageCalibration": {
"text": "",
"text2": [
"text2": [
"Calibreer",
"voedingsspanning?"
],
"desc": "VIN Calibreren. Bevestigen door knoppen lang in te drukken."
},
"AdvancedSoldering": {
"text": "",
"text2": [
"text2": [
"Gedetailleerd",
"soldeerscherm"
],
"desc": "Gedetailleerde informatie in kleiner lettertype in soldeerscherm."
},
"ScrollingSpeed": {
"text": "",
"text2": [
"text2": [
"Scrol",
"snelheid"
],
"desc": "Scrolsnelheid van de tekst."
},
"TipModel": {
"text": "PUNTMO",
"text2": [
"text2": [
"Punt",
"Model"
],
"desc": "Gekozen punt"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Eenvoudige",
"Calibrering"
],
"desc": "Calibrering met heet water"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Gevorderde",
"Calibrering"
],
"desc": "Calibrering met thermokoppel"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Vermogen",
"Watt"
],
"desc": "Vermogen van de adapter"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "I"
},
"menuDouble": false,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "Kilde",
"text2": [
"",
"text2": [
"Kilde",
""
],
"desc": "Strømforsyning. Sett nedre spenning for automatisk nedstenging. <DC 10V <S 3.3V per celle"
},
"SleepTemperature": {
"text": "DTmp",
"text2": [
"",
"text2": [
"DTmp",
""
],
"desc": "Dvaletemperatur <C"
"desc": "Dvaletemperatur <C>"
},
"SleepTimeout": {
"text": "DTid",
"text2": [
"text2": [
"",
""
],
"desc": "Tid før dvale <Minutter/Sekunder"
},
"ShutdownTimeout": {
"text": "AvTid",
"text2": [
"",
"text2": [
"AvTid",
""
],
"desc": "Tid før automatisk nedstenging <Minutter"
},
"MotionSensitivity": {
"text": "BSensr",
"text2": [
"",
"text2": [
"BSensr",
""
],
"desc": "Bevegelsesfølsomhet <0.Inaktiv 1.Minst følsom 9.Mest følsom"
},
"TemperatureUnit": {
"text": "TmpEnh",
"text2": [
"",
"text2": [
"TmpEnh",
""
],
"desc": "Temperaturskala <C=Celsius F=Fahrenheit"
},
"AdvancedIdle": {
"text": "AvDvSk",
"text2": [
"",
"text2": [
"AvDvSk",
""
],
"desc": "Vis detaljert informasjon med liten skrift på dvaleskjermen."
},
"DisplayRotation": {
"text": "SkRetn",
"text2": [
"",
"text2": [
"SkRetn",
""
],
"desc": "Skjermretning <A. Automatisk V. Venstrehendt H. Høyrehendt"
},
"BoostEnabled": {
"text": "Kraft",
"text2": [
"",
""
],
"desc": "Frontknappen aktiverer kraftfunksjonen, 450C ved lodding"
},
"BoostTemperature": {
"text": "KTmp",
"text2": [
"",
"text2": [
"KTmp",
""
],
"desc": "Temperatur i \"kraft\"-modus"
},
"AutoStart": {
"text": "AStart",
"text2": [
"",
"text2": [
"AStart",
""
],
"desc": "Start automatisk med lodding når strøm kobles til. L=Lodding, D=Dvale, I=Inaktiv"
},
"CooldownBlink": {
"text": "KjBlnk",
"text2": [
"",
"text2": [
"KjBlnk",
""
],
"desc": "Blink temperaturen på skjermen mens spissen fortsatt er varm."
},
"TemperatureCalibration": {
"text": "TempKal?",
"text2": [
"",
"text2": [
"TempKal?",
""
],
"desc": "Kalibrer spiss-temperatur."
},
"SettingsReset": {
"text": "TilbStl?",
"text2": [
"",
"text2": [
"TilbStl?",
""
],
"desc": "Tilbakestill alle innstillinger"
},
"VoltageCalibration": {
"text": "KalSpIn?",
"text2": [
"",
"text2": [
"KalSpIn?",
""
],
"desc": "Kalibrer spenning. Knappene justerer. Langt trykk for å gå ut"
},
"AdvancedSoldering": {
"text": "AvLdSk",
"text2": [
"",
"text2": [
"AvLdSk",
""
],
"desc": "Vis detaljert informasjon ved lodding"
},
"ScrollingSpeed": {
"text": "RullHa",
"text2": [
"",
"text2": [
"RullHa",
""
],
"desc": "Hastigheten på rulletekst"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Tip",
"Model"
],
"desc": "Tip Model selection"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Simple",
"Calibration"
],
"desc": "Simple Calibration using Hot water"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Advanced",
"Calibration"
],
"desc": "Advanced calibration using thermocouple on the tip"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Power",
"Wattage"
],
"desc": "Power Wattage of the power adapter used"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -2,9 +2,10 @@
"languageCode": "PL",
"languageLocalName": "Polski",
"cyrillicGlyphs": false,
"tempUnitFahrenheit": false,
"messages": {
"SettingsCalibrationDone": "Kalibracja udana!",
"SettingsCalibrationWarning": "Przed kontynuowaniem upewnij się, że końcówka osiągnela temperature pokojowa!",
"SettingsCalibrationWarning": "Przed kontynuowaniem upewnij się, że końcówka osiągnęła temperaturę pokojową!",
"SettingsResetWarning": "Czy na pewno chcesz przywrócić ustawienia fabryczne?",
"UVLOWarningString": "NISKIE DC",
"UndervoltageString": "Pod napięciem",
@@ -12,7 +13,7 @@
"WarningTipTempString": "Temperatura grota: ",
"BadTipString": "ZŁY GROT",
"SleepingSimpleString": "Zzz!",
"SleepingAdvancedString": "Uspienie...",
"SleepingAdvancedString": "Uśpienie...",
"WarningSimpleString": "HOT!",
"WarningAdvancedString": "GORĄCA KOŃCÓWKA!",
"SleepingTipAdvancedString": "Grot:",
@@ -21,20 +22,21 @@
"TipDisconnectedString": "GROT ODŁĄCZONY",
"SolderingAdvancedPowerPrompt": "Power: ",
"OffString": "Wyłącz",
"ResetOKMessage": "Reset OK"
"ResetOKMessage": "Reset OK",
"YourGainMessage": "Twój zysk:",
"SettingsResetMessage": "Ustawienia zostały\nzresetowane!"
},
"characters": {
"SettingRightChar": "P",
"SettingLeftChar": "L",
"SettingAutoChar": "A",
"SettingFastChar": "F",
"SettingSlowChar": "S",
"SettingFastChar": "S",
"SettingSlowChar": "W",
"SettingStartSolderingChar": "T",
"SettingStartSleepChar": "S",
"SettingStartSleepChar": "Z",
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "N"
"SettingStartNoneChar": "B"
},
"menuDouble": false,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,228 +69,186 @@
},
"menuOptions": {
"PowerSource": {
"text": "PWRSC",
"text2": [
"text2": [
"Źródło",
"zasilania"
],
"desc": "Źródło zasilania. Ustaw napięcie odcięcia. <DC 10V> <S 3.3V dla ogniw Li>"
},
"SleepTemperature": {
"text": "STMP",
"text2": [
"text2": [
"Temperatura",
"uśpienia"
],
"desc": "Temperatura uśpienia <°C>"
},
"SleepTimeout": {
"text": "STME",
"text2": [
"text2": [
"Czas",
"uśpienia"
],
"desc": "Czas uśpienia <Minuty/Sekundy>"
"desc": "Czas uśpienia <minuty/sekundy>"
},
"ShutdownTimeout": {
"text": "SHTME",
"text2": [
"text2": [
"Czas",
"wyłączenia"
],
"desc": "Czas wyłączenia <Minuty>"
"desc": "Czas wyłączenia <minuty>"
},
"MotionSensitivity": {
"text": "MSENSE",
"text2": [
"text2": [
"Czułość",
"ruchu"
],
"desc": "Czułość ruchu <0.Wyłączona 1.minimalna 9.maksymalna>"
"desc": "Czułość ruchu <0.Wyłączona 1.Minimalna 9.Maksymalna>"
},
"TemperatureUnit": {
"text": "TMPUNT",
"text2": [
"text2": [
"Jednostka",
"temperatury"
],
"desc": "Jednostka temperatury <C=Celsius F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "ADVIDL",
"text2": [
"text2": [
"Mniejsza",
"czcionka"
],
"desc": "Wyświetla szczegółowe informacje za pomocą mniejszej czcionki na ekranie bezczynnośći <T = wł., N = wył.>"
"desc": "Wyświetla szczegółowe informacje za pomocą mniejszej czcionki na ekranie bezczynności"
},
"DisplayRotation": {
"text": "DSPROT",
"text2": [
"text2": [
"Orientacja",
"wyświetlacza"
],
"desc": "Orientacja wyświetlacza <A. Automatyczna L. Leworęczna P. Praworęczna>"
},
"BoostEnabled": {
"text": "BOOST",
"text2": [
"",
""
],
"desc": "Użyj przycisku przedniego w celu zwiększenia temperatury <T = wł., N = wył.>"
"desc": "Orientacja wyświetlacza <A - automatyczna, L - leworęczna, P - praworęczna>"
},
"BoostTemperature": {
"text": "BTMP",
"text2": [
"text2": [
"Temperatura",
"w trybie boost"
],
"desc": "Temperatura w trybie \"boost\" "
},
"AutoStart": {
"text": "ASTART",
"text2": [
"text2": [
"Automatyczne",
"uruchamianie"
],
"desc": "Automatyczne uruchamianie trybu lutowania po włączeniu zasilania. T=Lutowanie, S= Tryb Uspienia ,N=Wyłącz"
"desc": "Automatyczne uruchamianie trybu lutowania po włączeniu zasilania.<B - wyłączone, T - lutowanie, Z - uśpienie, O - uśpienie w temp. pokojowej"
},
"CooldownBlink": {
"text": "CLBLNK",
"text2": [
"text2": [
"Migająca",
"temperatura"
],
"desc": "Temperatura na ekranie miga, gdy grot jest jeszcze gorący. <T = wł., N = wył.>"
"desc": "Temperatura na ekranie miga, gdy grot jest jeszcze gorący."
},
"TemperatureCalibration": {
"text": "TMP CAL?",
"text2": [
"text2": [
"Kalibracja",
"temp. grota"
],
"desc": "Kalibracja temperatury grota lutownicy"
},
"SettingsReset": {
"text": "RESET?",
"text2": [
"",
""
"text2": [
"Ustawienia",
"fabryczne"
],
"desc": "Zresetuj wszystkie ustawienia"
"desc": "Zresetuje wszystkie ustawienia!"
},
"VoltageCalibration": {
"text": "CAL VIN?",
"text2": [
"text2": [
"Kalibracja",
"napięcia"
],
"desc": "Kalibracja napięcia wejściowego. Krótkie naciśnięcie, aby ustawić, długie naciśnięcie, aby wyjść."
},
"AdvancedSoldering": {
"text": "ADVSLD",
"text2": [
"text2": [
"Szczegółowe",
"informacje"
],
"desc": "Wyświetl szczegółowe informacje podczas lutowania <T = wł., N = wył.>"
"desc": "Wyświetl szczegółowe informacje podczas lutowania"
},
"ScrollingSpeed": {
"text": "DESCSP",
"text2": [
"text2": [
"Szybkość",
"tekstu"
],
"desc": "Szybkość przewijania tekstu"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Model",
"grota"
],
"desc": "Wybór grotu"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Prosta",
"Kalibracja"
"kalibracja"
],
"desc": "Prosta kalibracja używając gorącej wody"
"desc": "Prosta kalibracja, używając gorącej wody"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Zaawansowana",
"Kalibracja"
"kalibracja"
],
"desc": "Zaawansowana kalibracja za pomocy termopoary na grocie"
"desc": "Zaawansowana kalibracja za pomocą termoelementu na grocie"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Moc",
"Wattach"
"w W"
],
"desc": "Moc używanego zasilacza w Watach"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
"desc": "Moc używanego zasilacza w Wattach"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"Power",
"Limit"
"text2": [
"Limit",
"mocy"
],
"desc": "Maximum power the iron can use <Watts>"
"desc": "Maksymalna moc w W, jakiej może użyć lutownica"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"Key +-",
"reverse?"
"text2": [
"Zamień przyciski",
"+ -"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
"desc": "Zamienia działanie przycisków zmiany temperatury grotu"
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"Temp change",
"short?"
"text2": [
"Szybka zmiana",
"temperatury"
],
"desc": "Temperature change steps on short button press!"
"desc": "Zmiany temperatury krok po korku, po krótkim naciśnięciu przycisku"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"Temp change",
"long?"
"text2": [
"Wolna zmiana",
"temperatury"
],
"desc": "Temperature change steps on long button press!"
"desc": "Zmiany temperatury krok po korku, po długim naciśnięciu przycisku"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"Power",
"Pulse W"
"text2": [
"Moc pulsu",
"w W"
],
"desc": "Keep awake pulse power intensity"
"desc": "Utrzymuj intensywność mocy pulsu"
},
"TipGain": {
"text": "TG",
"text2": [
"Modify",
"tip gain"
"text2": [
"Zmodyfikowany",
"zysk grotu"
],
"desc": "Tip gain"
"desc": "Zysk grotu"
}
}
}

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "FONTE",
"text2": [
"text2": [
"Fonte",
"alimentação"
],
"desc": "Fonte de alimentação. Define a tensão de corte. <DC=10V> <S=3.3V/célula>"
},
"SleepTemperature": {
"text": "TMPE",
"text2": [
"text2": [
"Temperat.",
"repouso"
],
"desc": "Temperatura de repouso <C>"
},
"SleepTimeout": {
"text": "TMPO",
"text2": [
"text2": [
"Tempo",
"repouso"
],
"desc": "Tempo para repouso <Minutos/Segundos>"
},
"ShutdownTimeout": {
"text": "DESLI",
"text2": [
"text2": [
"Tempo",
"desligam."
],
"desc": "Tempo para desligamento <Minutos>"
},
"MotionSensitivity": {
"text": "MOVIME",
"text2": [
"text2": [
"Sensibilidade",
"movimento"
],
"desc": "Sensibilidade ao movimento <0=Desligado 1=Menor 9=Maior>"
},
"TemperatureUnit": {
"text": "UNIDAD",
"text2": [
"text2": [
"Unidade",
"temperatura"
],
"desc": "Unidade de temperatura <C=Celsius F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "EM ESPERA",
"text2": [
"text2": [
"Tela repouso",
"avançada"
],
"desc": "Exibe informações avançadas quando em espera"
},
"DisplayRotation": {
"text": "ORIENT",
"text2": [
"text2": [
"Orientação",
"tela"
],
"desc": "Orientação da tela <A.utomática C.anhoto D.estro>"
},
"BoostEnabled": {
"text": "TURBO",
"text2": [
"Modo turbo",
"activado"
],
"desc": "Tecla frontal activa modo \"turbo\""
},
"BoostTemperature": {
"text": "TTMP",
"text2": [
"text2": [
"Modo turbo",
"temperat."
],
"desc": "Ajuste de temperatura do modo \"turbo\""
},
"AutoStart": {
"text": "MODOAT",
"text2": [
"text2": [
"Partida",
"automática"
],
"desc": "Aquece a ponta automaticamente ao ligar"
},
"CooldownBlink": {
"text": "RESFRI",
"text2": [
"text2": [
"Piscar ao",
"arrefecer"
],
"desc": "Faz o valor da temperatura piscar durante o arrefecimento"
},
"TemperatureCalibration": {
"text": "CAL.TEMP",
"text2": [
"text2": [
"Calibrar",
"temperatura"
],
"desc": "Calibra a temperatura"
},
"SettingsReset": {
"text": "RESET",
"text2": [
"text2": [
"Reset de",
"fábrica?"
],
"desc": "Reverte todos ajustes"
},
"VoltageCalibration": {
"text": "CAL.VOLT",
"text2": [
"text2": [
"Calibrar",
"tensão"
],
"desc": "Calibra a tensão de alimentação. Use os botões para ajustar o valor. Mantenha pressionado para sair"
},
"AdvancedSoldering": {
"text": "AVNCAD",
"text2": [
"text2": [
"Tela trabalho",
"avançada"
],
"desc": "Exibe informações avançadas durante o uso"
},
"ScrollingSpeed": {
"text": "DESCSP",
"text2": [
"text2": [
"Velocidade",
"texto ajuda"
],
"desc": "Velocidade a que o texto é exibido"
},
"TipModel": {
"text": "MODPNT",
"text2": [
"text2": [
"Ponta",
"Modelo"
],
"desc": "Selecção de modelo de ponta"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Calibração",
"Simples"
],
"desc": "Calibração simples com água quente"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Calibração",
"Avançada"
],
"desc": "Calibração avançada com um termopar na ponta"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Potência",
"Fonte"
],
"desc": "Potência da fonte usada (Watt)"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -4,8 +4,8 @@
"cyrillicGlyphs": true,
"messages": {
"SettingsCalibrationDone": "Калибровка завершена!",
"SettingsCalibrationWarning": "Прежде чем продолжить, пожалуйста, убедитесь что жало имеет комнатную температуру!",
"SettingsResetWarning": "Вы уверены, что хотите сбросить настройки к значениям по-умолчанию?",
"SettingsCalibrationWarning": "Прежде чем продолжить, пожалуйста, убедитесь, что жало имеет комнатную температуру!",
"SettingsResetWarning": "Вы уверены, что хотите сбросить настройки к значениям по умолчанию?",
"UVLOWarningString": "НАПРЯЖ--",
"UndervoltageString": "Низк. напряжение",
"InputVoltageString": "Питание В: ",
@@ -36,7 +36,6 @@
"SettingStartSleepOffChar": "К",
"SettingStartNoneChar": "В"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -50,247 +49,205 @@
"Режимы",
"сна"
],
"desc": "Найстроки режима ожидания"
"desc": "Настройки режима ожидания"
},
"UIMenu": {
"text2": [
"Параметры",
"интерфейса"
],
"desc": "Найстройки пользовательского интерфейса"
"desc": "Настройки пользовательского интерфейса"
},
"AdvancedMenu": {
"text2": [
"Дополнител.",
"найстройки"
"настройки"
],
"desc": "Дополнительные настройки"
}
},
"menuOptions": {
"PowerSource": {
"text": "ИстчнПит",
"text2": [
"text2": [
"Источник",
"питания"
],
"desc": "Источник питания. Устанавливает напряжение отсечки. <DC 10В> <S 3.3В на ячейку, без лимита мощности>"
},
"SleepTemperature": {
"text": "ТмпОжд",
"text2": [
"text2": [
"Темп.",
"ожидания"
],
"desc": "Температура режима ожидания"
},
"SleepTimeout": {
"text": "ВрмОжид",
"text2": [
"text2": [
"Таймаут",
"ожидания"
],
"desc": "Время до перехода в режим ожидания <Минуты/Секунды>"
},
"ShutdownTimeout": {
"text": "ВрмОткл",
"text2": [
"text2": [
"Таймаут",
"выключения"
],
"desc": "Время до отключения паяльника <Минуты>"
},
"MotionSensitivity": {
"text": "ЧувсАксл",
"text2": [
"text2": [
"Чувствительн.",
"акселерометра"
],
"desc": "Чувствительность акселерометра <0=Выкл., 1=Мин., 9=Макс.>"
},
"TemperatureUnit": {
"text": "ЕдТемп",
"text2": [
"text2": [
"Единицы",
"температуры"
],
"desc": "Единицы изменения температуры <C=Цельция, F=Фаренгейта>"
"desc": "Единицы измерения температуры <C=Цельcия, F=Фаренгейта>"
},
"AdvancedIdle": {
"text": "ИнфОжд",
"text2": [
"text2": [
"Подробный",
"реж. ожидания"
],
"desc": "Отображать детальную информацию уменьшенным шрифтом на домашнем экране"
"desc": "Отображать детальную информацию уменьшенным шрифтом на экране ожидания"
},
"DisplayRotation": {
"text": "ПовЭкр",
"text2": [
"text2": [
"Ориентация",
"экрана"
],
"desc": "Ориентация экрана <А=Авто, Л=Левая рука, П=Правая рука>"
},
"BoostEnabled": {
"text": "Турб",
"text2": [
"Турбо",
"режим"
],
"desc": "Включить активацию турбо-режма, при удержании ближней к жалу кнопки во время пайки"
},
"BoostTemperature": {
"text": "ТемпТурб",
"text2": [
"text2": [
"t° турбо",
"режима"
],
"desc": "Температура жала в турбо режиме"
"desc": "Температура жала в турбо-режиме"
},
"AutoStart": {
"text": "АвтоРеж",
"text2": [
"text2": [
"Авто",
"старт"
],
"desc": "Режим с которым запускается паяльник при подаче питания <П=Пайка, О=Ожидание, К=Ожидание при комн. темп., В=Выкл.>"
"desc": "Режим, в котором запускается паяльник при подаче питания <П=Пайка, О=Ожидание, К=Ожидание при комн. темп., В=Выкл.>"
},
"CooldownBlink": {
"text": "МигТемп",
"text2": [
"text2": [
"Мигание t°",
"при остывании"
],
"desc": "Мигать температурой на экране охлаждения, пока жало еще горячее"
},
"TemperatureCalibration": {
"text": "КалТемп?",
"text2": [
"text2": [
"Калибровка",
"температуры"
],
"desc": "Калибровка термодатчика жала"
},
"SettingsReset": {
"text": "Сброс?",
"text2": [
"text2": [
"Сброс",
"Настроек"
],
"desc": "Сброс настроек к значеням по-умолчанию"
"desc": "Сброс настроек к значеням по умолчанию"
},
"VoltageCalibration": {
"text": "КалНапр",
"text2": [
"text2": [
"Калибровка",
"напряжения"
],
"desc": "Калибровка входного напряжения <длинное нажатие для выхода>"
},
"AdvancedSoldering": {
"text": "ИнфПайк",
"text2": [
"text2": [
"Подробный",
"экран пайки"
],
"desc": "Показывать детальную информацию на экране пайки"
},
"ScrollingSpeed": {
"text": "СкорТекс",
"text2": [
"text2": [
"Скорость",
"текста"
],
"desc": "Скорость прокрутки текста <М=медленно, Б=быстро>"
},
"TipModel": {
"text": "МодЖала",
"text2": [
"text2": [
"Модель",
"жала"
],
"desc": "Выбор модели жала"
},
"SimpleCalibrationMode": {
"text": "УпрКал",
"text2": [
"text2": [
"Упрощенная",
"калибровка"
],
"desc": "Упрощенная калибровка с использованием горячей воды"
},
"AdvancedCalibrationMode": {
"text": "УлучшКал",
"text2": [
"text2": [
"Улучшенная",
"калибровка"
],
"desc": "Улучшенная калибровка с импользованием термопары жала"
},
"PowerInput": {
"text": "МощнИст",
"text2": [
"text2": [
"Мощность",
"питания"
],
"desc": "Мощность используемого источника питания"
},
"PowerLimitEnable": {
"text": "ВклЛимW",
"text2": [
"Ограничение",
"мощности"
],
"desc": "Включить лимит потреблямой мощности"
},
"PowerLimit": {
"text": "ЗначЛимW",
"text2": [
"text2": [
"Максимальная",
"мощность"
],
"desc": "Максимальная мощность которую может использовать паяльник <Ватт>"
"desc": "Максимальная мощность, которую может использовать паяльник <Ватт>"
},
"ReverseButtonTempChange": {
"text": "ИнвКноп",
"text2": [
"text2": [
"Инвертировать",
"кнопки"
],
"desc": "Инвертировать кнопки изменения температуры"
},
"TempChangeShortStep": {
"text": "ШагКорт",
"text2": [
"text2": [
"Шаг темп.",
"кор. наж."
],
"desc": "Шаг изменения температуры при коротком нажатии кнопок"
},
"TempChangeLongStep": {
"text": "ШагДлин",
"text2": [
"text2": [
"Шаг темп.",
"длин. наж."
],
"desc": "Шаг изменения температуры при длинном нажатии кнопок"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],
"desc": "Tip gain"
}
}
}
}

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": false,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "PWRSC",
"text2": [
"",
"text2": [
"PWRSC",
""
],
"desc": "Zdroj napatia. Nastavit napatie pre vypnutie (cutoff) <DC=10V, nS=n*3.3V pre LiIon clanky>"
},
"SleepTemperature": {
"text": "STMP",
"text2": [
"",
"text2": [
"STMP",
""
],
"desc": "Kludova teplota (v nastavenych jednotkach)"
},
"SleepTimeout": {
"text": "STME",
"text2": [
"",
"text2": [
"STME",
""
],
"desc": "Kludovy rezim po <sekundach/minutach>"
},
"ShutdownTimeout": {
"text": "SHTME",
"text2": [
"",
"text2": [
"SHTME",
""
],
"desc": "Cas na vypnutie <minuty>"
},
"MotionSensitivity": {
"text": "MSENSE",
"text2": [
"",
"text2": [
"MSENSE",
""
],
"desc": "Citlivost detekcie pohybu <0=Vyp, 1=Min ... 9=Max>"
},
"TemperatureUnit": {
"text": "TMPUNT",
"text2": [
"",
"text2": [
"TMPUNT",
""
],
"desc": "Jednotky merania teploty <C=stupne Celzia, F=stupne Fahrenheita>"
},
"AdvancedIdle": {
"text": "ADVIDL",
"text2": [
"",
"text2": [
"ADVIDL",
""
],
"desc": "Zobrazit detailne informacie v kludovom rezime <T=Zap, F=Vyp>"
},
"DisplayRotation": {
"text": "DSPROT",
"text2": [
"",
"text2": [
"DSPROT",
""
],
"desc": "Orientacia displeja <A=Auto, L=Lavak, R=Pravak>"
},
"BoostEnabled": {
"text": "BOOST",
"text2": [
"",
""
],
"desc": "Povolit tlacidlo pre prudky nahrev <T=Zap, F=Vyp>"
},
"BoostTemperature": {
"text": "BTMP",
"text2": [
"",
"text2": [
"BTMP",
""
],
"desc": "Cielova teplota pre prudky nahrev (v nastavenych jednotkach)"
},
"AutoStart": {
"text": "ASTART",
"text2": [
"",
"text2": [
"ASTART",
""
],
"desc": "Pri starte spustit rezim spajkovania <T=Zap, F=Vyp, S=Spanok>"
},
"CooldownBlink": {
"text": "CLBLNK",
"text2": [
"",
"text2": [
"CLBLNK",
""
],
"desc": "Blikanie ukazovatela teploty pocas chladnutia hrotu <T=Zap, F=Vyp>"
},
"TemperatureCalibration": {
"text": "TMP CAL?",
"text2": [
"",
"text2": [
"TMP CAL?",
""
],
"desc": "Kalibracia posunu hrotu"
},
"SettingsReset": {
"text": "RESET?",
"text2": [
"",
"text2": [
"RESET?",
""
],
"desc": "Tovarenske nastavenia"
},
"VoltageCalibration": {
"text": "CAL VIN?",
"text2": [
"",
"text2": [
"CAL VIN?",
""
],
"desc": "Kalibracia VIN. Kratke stlacenie meni nastavenie, dlhe stlacenie pre navrat"
},
"AdvancedSoldering": {
"text": "ADVSLD",
"text2": [
"",
"text2": [
"ADVSLD",
""
],
"desc": "Zobrazenie detailov pocas spajkovania <T=Zap, F=Vyp>"
},
"ScrollingSpeed": {
"text": "DESCSP",
"text2": [
"",
"text2": [
"DESCSP",
""
],
"desc": "Speed this text scrolls past at"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Tip",
"Model"
],
"desc": "Tip Model selection"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Simple",
"Calibration"
],
"desc": "Simple Calibration using Hot water"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Advanced",
"Calibration"
],
"desc": "Advanced calibration using thermocouple on the tip"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Power",
"Wattage"
],
"desc": "Power Wattage of the power adapter used"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -35,7 +35,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -68,224 +67,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "PWRSC",
"text2": [
"text2": [
"Vir",
"napajanja"
],
"desc": "Vir napajanja. Nastavi napetost izklopa. <DC 10V> <S 3.3V na celico>"
},
"SleepTemperature": {
"text": "STMP",
"text2": [
"text2": [
"Temp. med",
"spanjem"
],
"desc": "Temperatura med spanjem <C>"
},
"SleepTimeout": {
"text": "STME",
"text2": [
"text2": [
"Čas do",
"spanja"
],
"desc": "Čas pred spanjem <minute/sekunde>"
},
"ShutdownTimeout": {
"text": "SHTME",
"text2": [
"text2": [
"Čas do",
"izklopa"
],
"desc": "Čas pred izklopom <minute>"
},
"MotionSensitivity": {
"text": "MSENSE",
"text2": [
"text2": [
"Občutljivost",
"premikanja"
],
"desc": "Občutljivost premikanja <0.izklopljeno 1.najmanj 9.najbolj občutljivo>"
},
"TemperatureUnit": {
"text": "TMPUNT",
"text2": [
"text2": [
"Enota za",
"temperaturo"
],
"desc": "Enota za temperaturo <C=celzija F=fahrenheita>"
},
"AdvancedIdle": {
"text": "ADVIDL",
"text2": [
"text2": [
"Več info na",
"zaslonu v mir"
],
"desc": "Prikaže več informacij z manjšo pisavo na zaslonu med mirovanjem."
},
"DisplayRotation": {
"text": "DSPROT",
"text2": [
"text2": [
"Orientacija",
"zaslona"
],
"desc": "Orientacija zaslona <S. samodejno L. levo D. desno>"
},
"BoostEnabled": {
"text": "BOOST",
"text2": [
"Omogoči",
"boost mode"
],
"desc": "Omogoči, da tipka za naprej zagreje konico na 450C."
},
"BoostTemperature": {
"text": "BTMP",
"text2": [
"text2": [
"Temperat.",
"v boost"
],
"desc": "Temperatura v \"boost\" načinu"
},
"AutoStart": {
"text": "ASTART",
"text2": [
"text2": [
"Samodejni",
"zagon"
],
"desc": "Samodejno segrej konico ob vklopu. T=segrej, S=spanje, F=izklop"
},
"CooldownBlink": {
"text": "CLBLNK",
"text2": [
"text2": [
"Utripanje med",
"hlajenjem"
],
"desc": "Utripaj temperaturo med hlajenjem, ko je konica še vroča."
},
"TemperatureCalibration": {
"text": "TMP CAL?",
"text2": [
"text2": [
"Kalibriram",
"temperaturo?"
],
"desc": "Kalibracija temperature na konici."
},
"SettingsReset": {
"text": "RESET?",
"text2": [
"text2": [
"Tovarniške",
"nastavitve?"
],
"desc": "Ponastavitev vseh nastavitev"
},
"VoltageCalibration": {
"text": "CAL VIN?",
"text2": [
"text2": [
"Kalibriram",
"vhodno napetost?"
],
"desc": "Kalibracija VIN. Nastavitve z gumbi, dolgi pritisk za izhod."
},
"AdvancedSoldering": {
"text": "ADVSLD",
"text2": [
"text2": [
"Več info na",
"zaslonu spaj."
],
"desc": "Prikaže več informacij z manjšo pisavo na zaslonu med spajkanjem."
},
"ScrollingSpeed": {
"text": "DESCSP",
"text2": [
"text2": [
"Hitrost",
"besedila"
],
"desc": "Hitrost, s katero se prikazuje besedilo"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Model",
"konice"
],
"desc": "Izbira tipa konice"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Preprosta",
"kalibracija"
],
"desc": "Preprosta kalibracija z vročo vodo."
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Napredna",
"kalibracija"
],
"desc": "Napredna kalibracija s termočlenom na konici"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Moč napajalnega",
"vira"
],
"desc": "Moč v W napajalnega vira"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "Нпјње",
"text2": [
"text2": [
"Врста",
"напајања"
],
"desc": "Тип напајања; одређује најнижи радни напон. <DC=адаптер (10V), S=батерија (3,3V по ћелији)>"
},
"SleepTemperature": {
"text": "ТСпв",
"text2": [
"text2": [
"Темп.",
"спавања"
],
"desc": "Температура на коју се спушта лемилица након одређеног времена мировања. <C/F>"
},
"SleepTimeout": {
"text": "ВСпв",
"text2": [
"text2": [
"Време до",
"спавања"
],
"desc": "Време мировања након кога лемилица спушта температуру. <M=минути, S=секунде>"
},
"ShutdownTimeout": {
"text": "ВГшњ",
"text2": [
"text2": [
"Време до",
"гашења"
],
"desc": "Време мировања након кога се лемилица гаси. <M=минути>"
},
"MotionSensitivity": {
"text": "ОстПкр",
"text2": [
"text2": [
"Осетљивост",
"на покрет"
],
"desc": "Осетљивост сензора покрета. <0=искључено, 1=најмање осетљиво, 9=најосетљивије>"
},
"TemperatureUnit": {
"text": "ЈедТмп",
"text2": [
"text2": [
"Јединица",
"температуре"
],
"desc": "Јединице у којима се приказује температура. <C=целзијус, F=фаренхајт>"
},
"AdvancedIdle": {
"text": "ДтљМир",
"text2": [
"text2": [
"Детаљи током",
"мировања"
],
"desc": "Приказивање детаљних информација на екрану током мировања."
},
"DisplayRotation": {
"text": "ОрјЕкр",
"text2": [
"text2": [
"Оријентација",
"екрана"
],
"desc": "Како је окренут екран. <А=аутоматски, Л=за леворуке, Д=за десноруке>"
},
"BoostEnabled": {
"text": "Пјчње",
"text2": [
"Појачање",
"омогућено"
],
"desc": "Држање предњег тастера током лемљења додатно појачава температуру врха."
},
"BoostTemperature": {
"text": "ТПјч",
"text2": [
"text2": [
"Темп.",
"појачања"
],
"desc": "Температура врха лемилице у току појачања."
},
"AutoStart": {
"text": "ВрћСта",
"text2": [
"text2": [
"Врући",
"старт"
],
"desc": "Лемилица одмах по покретању прелази у режим лемљења и греје се."
},
"CooldownBlink": {
"text": "УпзХла",
"text2": [
"text2": [
"Упозорење",
"при хлађењу"
],
"desc": "Приказ температуре трепће приликом хлађења докле год је врх и даље врућ."
},
"TemperatureCalibration": {
"text": "КалбрТмп",
"text2": [
"text2": [
"Калибрација",
"температуре"
],
"desc": "Калибрисање одступања температуре врха у односу на дршку."
},
"SettingsReset": {
"text": "ФабрПост",
"text2": [
"text2": [
"Фабричке",
"поставке"
],
"desc": "Враћање свих поставки на фабричке вредности."
},
"VoltageCalibration": {
"text": "КалбрНап",
"text2": [
"text2": [
"Калибрација",
"улазног напона"
],
"desc": "Калибрисање улазног напона. Подешава се на тастере; дуги притисак за крај."
},
"AdvancedSoldering": {
"text": "ДтљЛем",
"text2": [
"text2": [
"Детаљи током",
"лемљења"
],
"desc": "Приказивање детаљних информација на екрану током лемљења."
},
"ScrollingSpeed": {
"text": "БрзПор",
"text2": [
"text2": [
"Брзина",
"порука"
],
"desc": "Брзина кретања описних порука попут ове. <С=споро, Б=брзо>"
},
"TipModel": {
"text": "МоделВрх",
"text2": [
"text2": [
"Модел",
"врха"
],
"desc": "Одабир модела лемног врха."
},
"SimpleCalibrationMode": {
"text": "ЈедКалбр",
"text2": [
"text2": [
"Једноставна",
"калибрација"
],
"desc": "Једноставна калибрација кипућом водом."
},
"AdvancedCalibrationMode": {
"text": "НапКалбр",
"text2": [
"text2": [
"Напредна",
"калибрација"
],
"desc": "Напредна калибрација помоћу термопара."
},
"PowerInput": {
"text": "УлазСнаг",
"text2": [
"text2": [
"Улазна",
"снага"
],
"desc": "Снага напајања у ватима."
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "Npjnj",
"text2": [
"text2": [
"Vrsta",
"napajanja"
],
"desc": "Tip napajanja; određuje najniži radni napon. <DC=adapter (10V), S=baterija (3,3V po ćeliji)>"
},
"SleepTemperature": {
"text": "TSpv",
"text2": [
"text2": [
"Temp.",
"spavanja"
],
"desc": "Temperatura na koju se spušta lemilica nakon određenog vremena mirovanja. <C/F>"
},
"SleepTimeout": {
"text": "VSpv",
"text2": [
"text2": [
"Vreme do",
"spavanja"
],
"desc": "Vreme mirovanja nakon koga lemilica spušta temperaturu. <M=minuti, S=sekunde>"
},
"ShutdownTimeout": {
"text": "VGšnj",
"text2": [
"text2": [
"Vreme do",
"gašenja"
],
"desc": "Vreme mirovanja nakon koga se lemilica gasi. <M=minuti>"
},
"MotionSensitivity": {
"text": "OstPkr",
"text2": [
"text2": [
"Osetljivost",
"na pokret"
],
"desc": "Osetljivost senzora pokreta. <0=isključeno, 1=najmanje osetljivo, 9=najosetljivije>"
},
"TemperatureUnit": {
"text": "JedTmp",
"text2": [
"text2": [
"Jedinica",
"temperature"
],
"desc": "Jedinice u kojima se prikazuje temperatura. <C=celzijus, F=farenhajt>"
},
"AdvancedIdle": {
"text": "DtlMir",
"text2": [
"text2": [
"Detalji tokom",
"mirovanja"
],
"desc": "Prikazivanje detaljnih informacija na ekranu tokom mirovanja."
},
"DisplayRotation": {
"text": "OrjEkr",
"text2": [
"text2": [
"Orijentacija",
"ekrana"
],
"desc": "Kako je okrenut ekran. <A=automatski, L=za levoruke, D=za desnoruke>"
},
"BoostEnabled": {
"text": "Pjčnj",
"text2": [
"Pojačanje",
"omogućeno"
],
"desc": "Držanje prednjeg tastera tokom lemljenja dodatno pojačava temperaturu vrha."
},
"BoostTemperature": {
"text": "TPjč",
"text2": [
"text2": [
"Temp.",
"pojačanja"
],
"desc": "Temperatura vrha lemilice u toku pojačanja."
},
"AutoStart": {
"text": "VrćSta",
"text2": [
"text2": [
"Vrući",
"start"
],
"desc": "Lemilica odmah po pokretanju prelazi u režim lemljenja i greje se."
},
"CooldownBlink": {
"text": "UpzHla",
"text2": [
"text2": [
"Upozorenje",
"pri hlađenju"
],
"desc": "Prikaz temperature trepće prilikom hlađenja dokle god je vrh i dalje vruć."
},
"TemperatureCalibration": {
"text": "KalbrTmp",
"text2": [
"text2": [
"Kalibracija",
"temperature"
],
"desc": "Kalibrisanje odstupanja temperature vrha u odnosu na dršku."
},
"SettingsReset": {
"text": "FabrPost",
"text2": [
"text2": [
"Fabričke",
"postavke"
],
"desc": "Vraćanje svih postavki na fabričke vrednosti."
},
"VoltageCalibration": {
"text": "KalbrNap",
"text2": [
"text2": [
"Kalibracija",
"ulaznog napona"
],
"desc": "Kalibrisanje ulaznog napona. Podešava se na tastere; dugi pritisak za kraj."
},
"AdvancedSoldering": {
"text": "DtlLem",
"text2": [
"text2": [
"Detalji tokom",
"lemljenja"
],
"desc": "Prikazivanje detaljnih informacija na ekranu tokom lemljenja."
},
"ScrollingSpeed": {
"text": "BrzPor",
"text2": [
"text2": [
"Brzina",
"poruka"
],
"desc": "Brzina kretanja opisnih poruka poput ove. <S=sporo, B=brzo>"
},
"TipModel": {
"text": "ModelVrh",
"text2": [
"text2": [
"Model",
"vrha"
],
"desc": "Odabir modela lemnog vrha."
},
"SimpleCalibrationMode": {
"text": "JedKalbr",
"text2": [
"text2": [
"Jednostavna",
"kalibracija"
],
"desc": "Jednostavna kalibracija kipućom vodom."
},
"AdvancedCalibrationMode": {
"text": "NapKalbr",
"text2": [
"text2": [
"Napredna",
"kalibracija"
],
"desc": "Napredna kalibracija pomoću termopara."
},
"PowerInput": {
"text": "UlazSnag",
"text2": [
"text2": [
"Ulazna",
"snaga"
],
"desc": "Snaga napajanja u vatima."
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "",
"text2": [
"text2": [
"Ström-",
"källa"
],
"desc": "Strömkälla. Anger lägsta spänning. <DC 10V> <S 3.3V per cell>"
},
"SleepTemperature": {
"text": "",
"text2": [
"text2": [
"Vilo-",
"temp"
],
"desc": "Vilotemperatur <C>"
},
"SleepTimeout": {
"text": "",
"text2": [
"text2": [
"Vilo-",
"timeout"
],
"desc": "Vilo-timeout <Minuter/Seconder>"
},
"ShutdownTimeout": {
"text": "",
"text2": [
"text2": [
"Avstängn.",
"timeout"
],
"desc": "Avstängnings-timeout <Minuter>"
},
"MotionSensitivity": {
"text": "",
"text2": [
"text2": [
"Rörelse-",
"känslighet"
],
"desc": "Rörelsekänslighet <0.Av 1.minst känslig 9.mest känslig>"
},
"TemperatureUnit": {
"text": "",
"text2": [
"text2": [
"Temperatur-",
"enheter"
],
"desc": "Temperaturenhet <C=Celsius F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "",
"text2": [
"text2": [
"Detaljerad",
"vid inaktiv"
],
"desc": "Visa detaljerad information i mindre typsnitt när inaktiv."
},
"DisplayRotation": {
"text": "",
"text2": [
"text2": [
"Visnings",
"läge"
],
"desc": "Visningsläge <A. Automatisk V. Vänsterhänt H. Högerhänt>"
},
"BoostEnabled": {
"text": "",
"text2": [
"Turboläge",
"aktiverat"
],
"desc": "Aktivera främre knappen för turboläge (temperaturhöjning) vid lödning"
},
"BoostTemperature": {
"text": "",
"text2": [
"text2": [
"Turbo-",
"temp"
],
"desc": "Temperatur i \"turbo\"-läge"
},
"AutoStart": {
"text": "",
"text2": [
"text2": [
"Auto",
"start"
],
"desc": "Startar automatiskt lödpennan vid uppstart. T=Lödning, S=Viloläge, F=Av"
},
"CooldownBlink": {
"text": "",
"text2": [
"text2": [
"Nedkylnings-",
"blink"
],
"desc": "Blinka temperaturen medan spetsen kyls av och fortfarande är varm."
},
"TemperatureCalibration": {
"text": "",
"text2": [
"text2": [
"Kalibrera",
"temperatur?"
],
"desc": "Kalibrera spets-kompensation."
},
"SettingsReset": {
"text": "",
"text2": [
"text2": [
"Fabriks-",
"inställ?"
],
"desc": "Återställ alla inställningar"
},
"VoltageCalibration": {
"text": "",
"text2": [
"text2": [
"Kalibrera",
"inspänning?"
],
"desc": "Inspänningskalibrering. Knapparna justerar, håll inne för avslut"
},
"AdvancedSoldering": {
"text": "",
"text2": [
"text2": [
"Detaljerad",
"lödng.skärm"
],
"desc": "Visa detaljerad information vid lödning"
},
"ScrollingSpeed": {
"text": "",
"text2": [
"text2": [
"Beskrivning",
"rullhast."
],
"desc": "Hastighet som den här texten rullar i"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Tip",
"Model"
],
"desc": "Tip Model selection"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Simple",
"Calibration"
],
"desc": "Simple Calibration using Hot water"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Advanced",
"Calibration"
],
"desc": "Advanced calibration using thermocouple on the tip"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Power",
"Wattage"
],
"desc": "Power Wattage of the power adapter used"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -34,7 +34,6 @@
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
},
"menuDouble": false,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +66,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "PWRSC",
"text2": [
"",
"text2": [
"PWRSC",
""
],
"desc": "Güç Kaynağı. kesim geriliminı ayarlar. <DC 10V> <S 3.3V hücre başına>"
},
"SleepTemperature": {
"text": "STMP",
"text2": [
"",
"text2": [
"STMP",
""
],
"desc": "Uyku Sıcaklığı <C>"
},
"SleepTimeout": {
"text": "STME",
"text2": [
"",
"text2": [
"STME",
""
],
"desc": "Uyku Zaman Aşımı <Dakika/Saniye>"
},
"ShutdownTimeout": {
"text": "SHTME",
"text2": [
"",
"text2": [
"SHTME",
""
],
"desc": "Kapatma Zaman Aşımı <Dakika>"
},
"MotionSensitivity": {
"text": "MSENSE",
"text2": [
"",
"text2": [
"MSENSE",
""
],
"desc": "Hareket Hassasiyeti <0.Kapalı 1.En az duyarlı 9.En duyarlı>"
},
"TemperatureUnit": {
"text": "TMPUNT",
"text2": [
"",
"text2": [
"TMPUNT",
""
],
"desc": "Sıcaklık Ünitesi <C=Celsius F=Fahrenheit>"
},
"AdvancedIdle": {
"text": "ADVIDL",
"text2": [
"",
"text2": [
"ADVIDL",
""
],
"desc": "Boş ekranda ayrıntılı bilgileri daha küçük bir yazı tipi ile göster."
},
"DisplayRotation": {
"text": "DSPROT",
"text2": [
"",
"text2": [
"DSPROT",
""
],
"desc": "Görüntü Yönlendirme <A. Otomatik L. Solak R. Sağlak>"
},
"BoostEnabled": {
"text": "BOOST",
"text2": [
"",
""
],
"desc": "Lehimleme yaparken ön tuşa basmak Boost moduna sokar(450C)"
},
"BoostTemperature": {
"text": "BTMP",
"text2": [
"",
"text2": [
"BTMP",
""
],
"desc": "\"boost\" Modu Derecesi"
},
"AutoStart": {
"text": "ASTART",
"text2": [
"",
"text2": [
"ASTART",
""
],
"desc": "Güç verildiğinde otomatik olarak lehimleme modunda başlat. T=Lehimleme Modu, S= Uyku Modu,F=Kapalı"
},
"CooldownBlink": {
"text": "CLBLNK",
"text2": [
"",
"text2": [
"CLBLNK",
""
],
"desc": "Soğutma ekranında uç hala sıcakken derece yanıp sönsün."
},
"TemperatureCalibration": {
"text": "TMP CAL?",
"text2": [
"",
"text2": [
"TMP CAL?",
""
],
"desc": "Ucu kalibre et."
},
"SettingsReset": {
"text": "RESET?",
"text2": [
"",
"text2": [
"RESET?",
""
],
"desc": "Bütün ayarları sıfırla"
},
"VoltageCalibration": {
"text": "CAL VIN?",
"text2": [
"",
"text2": [
"CAL VIN?",
""
],
"desc": "VIN Kalibrasyonu. Düğmeler ayarlar, çıkmak için uzun bas."
},
"AdvancedSoldering": {
"text": "ADVSLD",
"text2": [
"",
"text2": [
"ADVSLD",
""
],
"desc": "Lehimleme yaparken detaylı bilgi göster"
},
"ScrollingSpeed": {
"text": "DESCSP",
"text2": [
"",
"text2": [
"DESCSP",
""
],
"desc": "Speed this text scrolls past at"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Uç",
"Modeli"
],
"desc": "Uç Modeli seçimi"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Basit",
"Kalibrasyon"
],
"desc": "Sıcak su kullanarak basit kalibrasyon"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Gelişmiş",
"Kalibrasyon"
],
"desc": "Uçtaki ısı sensörünü kullanarak gelişmiş kalibrasyon"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Güç",
"Miktarı(W)"
],
"desc": "Kullanılan adaptörün güç miktarı"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"P Limit",
"Enable"
],
"desc": "Enable power limit"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"text2": [
"Power",
"Limit"
],
"desc": "Maximum power the iron can use <Watts>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Key +-",
"reverse?"
],
"desc": "Reverse the tip temperature change buttons plus minus assignment."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"text2": [
"Temp change",
"short?"
],
"desc": "Temperature change steps on short button press!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"text2": [
"Temp change",
"long?"
],
"desc": "Temperature change steps on long button press!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"text2": [
"Power",
"Pulse W"
],
"desc": "Keep awake pulse power intensity"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -5,36 +5,37 @@
"messages": {
"SettingsCalibrationDone": "Калібрування виконане!",
"SettingsCalibrationWarning": "Переконайтеся, що жало охололо до кімнатної температури, перш ніж продовжувати!",
"SettingsResetWarning": "Ви дійсно хочете скинути налаштування до значень за замовчуванням?",
"SettingsResetWarning": "Ви дійсно хочете скинути налаштування до значень за замовчуванням? <A - Так, В - Ні>",
"UVLOWarningString": "АККУМ--",
"UndervoltageString": "Під живленням",
"UndervoltageString": "Низ. напруга",
"InputVoltageString": "Жив.(B): ",
"WarningTipTempString": "Жало t°: ",
"BadTipString": ало--",
"SleepingSimpleString": "Сон ",
"BadTipString": АЛО--",
"SleepingSimpleString": "ZzZzz",
"SleepingAdvancedString": "Очікування...",
"WarningSimpleString": "АЙ!",
"WarningAdvancedString": "УВАГА ГАРЯЧЕ!",
"WarningSimpleString": "ГАРЯЧЕ!",
"WarningAdvancedString": "!!! ГАРЯЧЕ ЖАЛО !!!",
"SleepingTipAdvancedString": "Жало:",
"IdleTipString": "Жало:",
"IdleSetString": " ->",
"TipDisconnectedString": "Жало вимкнено!",
"SolderingAdvancedPowerPrompt": "Живлення: ",
"OffString": "Вимк",
"ResetOKMessage": "Reset OK"
"ResetOKMessage": "Скидання OK",
"YourGainMessage": "Приріст:",
"SettingsResetMessage": "Налаштування скинуті!"
},
"characters": {
"SettingRightChar": "П",
"SettingLeftChar": "Л",
"SettingAutoChar": "A",
"SettingFastChar": "+",
"SettingSlowChar": "-",
"SettingStartSolderingChar": "T",
"SettingStartSleepChar": "S",
"SettingStartSleepOffChar": "O",
"SettingStartNoneChar": "F"
"SettingFastChar": "Ш",
"SettingSlowChar": "П",
"SettingStartSolderingChar": "П",
"SettingStartSleepChar": "О",
"SettingStartSleepOffChar": "К",
"SettingStartNoneChar": "В"
},
"menuDouble": true,
"menuGroups": {
"SolderingMenu": {
"text2": [
@@ -67,224 +68,182 @@
},
"menuOptions": {
"PowerSource": {
"text": "ДжЖив",
"text2": [
"text2": [
"Джерело",
"живлення"
],
"desc": "Встановлення напруги відключення. <DC - 10V, 3S - 9.9V, 4S - 13.2V, 5S - 16.5V, 6S - 19.8V>"
},
"SleepTemperature": {
"text": "",
"text2": [
"text2": [
"Темпер.",
"сну"
],
"desc": "Температура режиму очікування <C°/F°>"
},
"SleepTimeout": {
"text": "",
"text2": [
"text2": [
"Тайм-аут",
"сну"
],
"desc": "Час до переходу в режим очікування <Хвилини>"
"desc": "Час до переходу в режим очікування <Хвилини/Секунди>"
},
"ShutdownTimeout": {
"text": "",
"text2": [
"text2": [
"Часу до",
"вимкнення"
],
"desc": "Час до відключення <Хвилини>"
},
"MotionSensitivity": {
"text": "",
"text2": [
"text2": [
"Чутл. сенсо-",
"ру руху"
],
"desc": "Акселерометр <0 - Вимк. 1 хв. чутливості 9 - макс. чутливості>"
"desc": "Акселерометр <0 - Вимк. 1 - мін. чутливості 9 - макс. чутливості>"
},
"TemperatureUnit": {
"text": "",
"text2": [
"text2": [
"Формат темпе-",
"ратури(C°/F°)"
],
"desc": "Одиниця виміру температури <C - Цельсій, F - Фаренгейт>"
},
"AdvancedIdle": {
"text": "",
"text2": [
"text2": [
"Детальний ре-",
"жим очікуван."
],
"desc": "Показувати детальну інформацію маленьким шрифтом на домашньому екрані"
},
"DisplayRotation": {
"text": "",
"text2": [
"text2": [
"Автоповорот",
"екрану"
],
"desc": "Орієнтація дисплея <A - Автоповорот, Л - Лівша, П - Правша>"
},
"BoostEnabled": {
"text": "",
"text2": [
"Режим",
"Турбо"
],
"desc": "Турбо-режим при утриманні кнопки А при пайці"
},
"BoostTemperature": {
"text": "",
"text2": [
"text2": [
"Темпер.",
"Турбо"
],
"desc": "Температура в Турбо-режимі"
},
"AutoStart": {
"text": "",
"text2": [
"text2": [
"Гарячий",
"старт"
],
"desc": "Автоматичний перехід в режим пайки при ввімкнені живлення."
"desc": "Режим з яким запускається паяльник при подачі живлення <П=Пайка, О=Очікування, К=Очікування при кімн. темп., В=Вимк.>"
},
"CooldownBlink": {
"text": "",
"text2": [
"text2": [
"Показ t° при",
"охолодж."
],
"desc": "Показувати температуру на екрані охолодження, поки жало залишається гарячим, при цьому екран моргає"
},
"TemperatureCalibration": {
"text": "",
"text2": [
"text2": [
"Калібровка",
"температури"
],
"desc": "Калібрування температурного датчика."
},
"SettingsReset": {
"text": "",
"text2": [
"text2": [
"Скинути всі",
"налаштування?"
],
"desc": "Скидання всіх параметрів до стандартних значень."
},
"VoltageCalibration": {
"text": "",
"text2": [
"text2": [
"Калібрування",
"напруги"
],
"desc": "Калібрування напруги входу. Налаштувати кнопками, натиснути і утримати щоб завершити."
},
"AdvancedSoldering": {
"text": "",
"text2": [
"text2": [
"Детальний ре-",
"жим пайки"
],
"desc": "Показувати детальну інформацію при пайці."
},
"ScrollingSpeed": {
"text": "",
"text2": [
"text2": [
"Швидкість",
"тексту"
],
"desc": "Швидкість прокрутки тексту"
"desc": "Швидкість прокрутки тексту <П=повільно, Ш=швидко>"
},
"TipModel": {
"text": "TIPMO",
"text2": [
"text2": [
"Модель",
"Жало"
],
"desc": "Вибір моделі жала"
},
"SimpleCalibrationMode": {
"text": "SMPCAL",
"text2": [
"text2": [
"Просте",
"Калібрування"
],
"desc": "Просте калібрування з використанням гарячої води"
},
"AdvancedCalibrationMode": {
"text": "ADVCAL",
"text2": [
"text2": [
"Детальне",
"Калібрування"
],
"desc": "Калібрування за допомогою термопари"
},
"PowerInput": {
"text": "PWRW",
"text2": [
"text2": [
"Потужність",
"дж. живл."
],
"desc": "Потужність джерела живлення в Ватах"
},
"PowerLimitEnable": {
"text": "PLIMEN",
"text2": [
"Ліміт",
"потужності"
],
"desc": "Вмикає обмеження потужності споживання"
},
"PowerLimit": {
"text": "PLIM",
"text2": [
"Максимальна",
"потужність"
"text2": [
"Макс.",
"потуж."
],
"desc": "Макс. потужність, яку може використовувати паяльник <Ват>"
},
"ReverseButtonTempChange": {
"text": "RVTCHG",
"text2": [
"text2": [
"Інвертувати",
"кнопки +-?"
],
"desc": "Інвертувати кнопки зміни температури."
},
"TempChangeShortStep": {
"text": "TCHGST",
"text2": [
"Зміна темп.",
"text2": [
"Зм. темп.",
"коротко?"
],
"desc": "Змінювати температуру при короткому натисканні!"
},
"TempChangeLongStep": {
"text": "TCHGLT",
"text2": [
"Зміна темп.",
"text2": [
"Зм. темп.",
"довго?"
],
"desc": "Змінювати температуру при довгому натисканні!"
},
"PowerPulsePower":{
"text": "POWPLS",
"text2": [
"Power",
"Pulse W"
"text2": [
"Пульс.",
"Навантаж."
],
"desc": "Keep awake pulse power intensity"
"desc": "Деякі PowerBank-и з часом вимк. живлення, якщо пристрій споживає дуже мало енергії (це потрібно щоб паяльник не вимкнувся з часом)"
},
"TipGain": {
"text": "TG",
"text2": [
"text2": [
"Modify",
"tip gain"
],

View File

@@ -193,11 +193,6 @@ var def =
"maxLen": 6,
"maxLen2": 13
},
{
"id": "BoostEnabled",
"maxLen": 6,
"maxLen2": 13
},
{
"id": "BoostTemperature",
"maxLen": 4,
@@ -258,11 +253,6 @@ var def =
"maxLen": 8,
"maxLen2": 16
},
{
"id": "PowerLimitEnable",
"maxLen": 6,
"maxLen2": 13
},
{
"id": "PowerLimit",
"maxLen": 5,

View File

@@ -1,8 +0,0 @@
builder:
build:
context: .
dockerfile: Dockerfile
cached: true
encrypted_env_file: ci/secrets/encrypted/deployment.encrypted
volumes:
- ./ci:/ci

View File

@@ -1,6 +0,0 @@
- type: parallel
name: Build the firmware
steps:
- name: build
service: builder
command: /build/ci/buildAll.sh

13
setup.sh Normal file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
set -e
# Setup shell file to setup the environment on an ubuntu machine
sudo apt-get update
sudo apt-get install -y make bzip2 git python3 wget
sudo mkdir /build
cd /build
sudo wget -qO- https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 | sudo tar -xj
# Add compiler to the path
sudo ln -s /build/gcc-arm-none-eabi-9-2020-q2-update/bin/* /usr/local/bin

View File

@@ -2,7 +2,7 @@
#include "BSP_Power.h"
#include "BSP_QC.h"
#include "Defines.h"
#include "UnitSettings.h"
#include "Model_Config.h"
#include "stdint.h"
/*
* BSP.h -- Board Support
@@ -47,8 +47,11 @@ void reboot();
// If the user has programmed in a bootup logo, draw it to the screen from flash
// Returns 1 if the logo was printed so that the unit waits for the timeout or button
uint8_t showBootLogoIfavailable();
//delay wrapper for delay using the hardware timer (used before RTOS)
void delay_ms(uint16_t count) ;
//Used to allow knowledge of if usb_pd is being used
uint8_t usb_pd_detect();
void delay_ms(uint16_t count);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,16 @@
/*
* BSP_PD.h
*
* Created on: 21 Jul 2020
* Author: Ralim
*/
#ifndef USER_BSP_PD_H_
#define USER_BSP_PD_H_
#include "BSP.h"
/*
* An array of all of the desired voltages & minimum currents in preferred order
*/
extern const uint16_t USB_PD_Desired_Levels[];
extern const uint8_t USB_PD_Desired_Levels_Len;
#endif /* USER_BSP_PD_H_ */

View File

@@ -12,9 +12,6 @@
extern "C" {
#endif
// Called once at startup, after RToS
// This can handle negotiations for QC/PD etc
void power_probe();
// Called periodically in the movement handling thread
// Can be used to check any details for the power system

View File

@@ -1,11 +1,13 @@
//BSP mapping functions
#include <IRQ.h>
#include "BSP.h"
#include "Setup.h"
#include "history.hpp"
#include "Pins.h"
#include "main.hpp"
#include "history.hpp"
#include "Model_Config.h"
#include "I2C_Wrapper.hpp"
volatile uint16_t PWMSafetyTimer = 0;
volatile uint8_t pendingPWM = 0;
@@ -15,8 +17,89 @@ history<uint16_t, PID_TIM_HZ> rawTempFilter = { { 0 }, 0, 0 };
void resetWatchdog() {
HAL_IWDG_Refresh(&hiwdg);
}
#ifdef TEMP_NTC
//Lookup table for the NTC
//Stored as ADCReading,Temp in degC
static const uint16_t NTCHandleLookup[] = {
//ADC Reading , Temp in C
29189, 0, //
29014, 1, //
28832, 2, //
28644, 3, //
28450, 4, //
28249, 5, //
28042, 6, //
27828, 7, //
27607, 8, //
27380, 9, //
27146, 10, //
26906, 11, //
26660, 12, //
26407, 13, //
26147, 14, //
25882, 15, //
25610, 16, //
25332, 17, //
25049, 18, //
24759, 19, //
24465, 20, //
24164, 21, //
23859, 22, //
23549, 23, //
23234, 24, //
22915, 25, //
22591, 26, //
22264, 27, //
21933, 28, //
21599, 29, //
// 21261, 30, //
// 20921, 31, //
// 20579, 32, //
// 20234, 33, //
// 19888, 34, //
// 19541, 35, //
// 19192, 36, //
// 18843, 37, //
// 18493, 38, //
// 18143, 39, //
// 17793, 40, //
// 17444, 41, //
// 17096, 42, //
// 16750, 43, //
// 16404, 44, //
// 16061, 45, //
// 15719, 46, //
// 15380, 47, //
// 15044, 48, //
// 14710, 49, //
// 14380, 50, //
// 14053, 51, //
// 13729, 52, //
// 13410, 53, //
// 13094, 54, //
// 12782, 55, //
// 12475, 56, //
// 12172, 57, //
// 11874, 58, //
// 11580, 59, //
// 11292, 60, //
};
#endif
uint16_t getHandleTemperature() {
#ifdef TEMP_NTC
//TS80P uses 100k NTC resistors instead
//NTCG104EF104FT1X from TDK
//For now not doing interpolation
int32_t result = getADC(0);
for (uint32_t i = 0; i < (sizeof(NTCHandleLookup) / (2 * sizeof(uint16_t)));
i++) {
if (result > NTCHandleLookup[(i * 2) + 0]) {
return NTCHandleLookup[(i * 2) + 1] * 10;
}
}
return 0;
#endif
#ifdef TEMP_TMP36
// We return the current handle temperature in X10 C
// TMP36 in handle, 0.5V offset and then 10mV per deg C (0.75V @ 25C for
// example) STM32 = 4096 count @ 3.3V input -> But We oversample by 32/(2^2) =
@@ -31,14 +114,15 @@ uint16_t getHandleTemperature() {
result *= 100;
result /= 993;
return result;
#endif
}
uint16_t getTipInstantTemperature() {
uint16_t sum = 0; // 12 bit readings * 8 -> 15 bits
uint16_t readings[8];
//Looking to reject the highest outlier readings.
//As on some hardware these samples can run into the op-amp recovery time
//Once this time is up the signal stabilises quickly, so no need to reject minimums
//Looking to reject the highest outlier readings.
//As on some hardware these samples can run into the op-amp recovery time
//Once this time is up the signal stabilises quickly, so no need to reject minimums
readings[0] = hadc1.Instance->JDR1;
readings[1] = hadc1.Instance->JDR2;
readings[2] = hadc1.Instance->JDR3;
@@ -65,10 +149,10 @@ uint16_t getTipRawTemp(uint8_t refresh) {
}
uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
// Therefore we can divide down from there
// Multiplying ADC max by 4 for additional calibration options,
// ideal term is 467
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
// Therefore we can divide down from there
// Multiplying ADC max by 4 for additional calibration options,
// ideal term is 467
#ifdef MODEL_TS100
#define BATTFILTERDEPTH 32
#else
@@ -93,6 +177,9 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
sum += samples[i];
sum /= BATTFILTERDEPTH;
if (divisor == 0) {
divisor = 1;
}
return sum * 4 / divisor;
}
@@ -139,13 +226,13 @@ void unstick_I2C() {
int timeout = 100;
int timeout_cnt = 0;
// 1. Clear PE bit.
// 1. Clear PE bit.
hi2c1.Instance->CR1 &= ~(0x0001);
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
// 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
// 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
@@ -172,7 +259,7 @@ void unstick_I2C() {
return;
}
// 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
// 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
@@ -186,20 +273,20 @@ void unstick_I2C() {
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
// 13. Set SWRST bit in I2Cx_CR1 register.
// 13. Set SWRST bit in I2Cx_CR1 register.
hi2c1.Instance->CR1 |= 0x8000;
asm("nop");
// 14. Clear SWRST bit in I2Cx_CR1 register.
// 14. Clear SWRST bit in I2Cx_CR1 register.
hi2c1.Instance->CR1 &= ~0x8000;
asm("nop");
// 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
// 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
hi2c1.Instance->CR1 |= 0x0001;
// Call initialization function.
// Call initialization function.
HAL_I2C_Init(&hi2c1);
}
@@ -212,42 +299,8 @@ uint8_t getButtonB() {
1 : 0;
}
/*
* Catch the IRQ that says that the conversion is done on the temperature
* readings coming in Once these have come in we can unblock the PID so that it
* runs again
*/
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (hadc == &hadc1) {
if (pidTaskNotification) {
vTaskNotifyGiveFromISR(pidTaskNotification,
&xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
}
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void reboot() {
NVIC_SystemReset();
}

View File

@@ -0,0 +1,22 @@
/*
* BSP_PD.c
*
* Created on: 21 Jul 2020
* Author: Ralim
*/
#include "BSP_PD.h"
#include "Model_Config.h"
#ifdef POW_PD
/*
* An array of all of the desired voltages & minimum currents in preferred order
*/
const uint16_t USB_PD_Desired_Levels[] = {
//mV desired input, mA minimum required current
12000, 2400, //12V @ 2.4A
9000, 2000, //9V @ 2A
5000, 100, //5V @ whatever
};
const uint8_t USB_PD_Desired_Levels_Len = 3;
#endif

View File

@@ -7,8 +7,7 @@
#include <I2C_Wrapper.hpp>
#include "BSP.h"
#include "Setup.h"
#define I2CUSESDMA
SemaphoreHandle_t FRToSI2C::I2CSemaphore;
SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr;
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
void FRToSI2C::CpltCallback() {
@@ -21,45 +20,22 @@ void FRToSI2C::CpltCallback() {
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size) {
if (I2CSemaphore == NULL) {
// no RToS, run blocking code
HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT,
pData, Size, 5000);
return true;
} else {
// RToS is active, run threading
// Get the mutex so we can use the I2C port
// Wait up to 1 second for the mutex
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
#ifdef I2CUSESDMA
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress,
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
if (!lock())
return false;
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress,
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
I2C_Unstick();
xSemaphoreGive(I2CSemaphore);
return false;
} else {
xSemaphoreGive(I2CSemaphore);
return true;
}
#else
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, Size,
5000)==HAL_OK){
xSemaphoreGive(I2CSemaphore);
return true;
}
xSemaphoreGive(I2CSemaphore);
return false;
#endif
} else {
return false;
}
I2C_Unstick();
unlock();
return false;
}
unlock();
return true;
}
void FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
Mem_Write(address, reg, &data, 1);
bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
return Mem_Write(address, reg, &data, 1);
}
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
@@ -67,76 +43,55 @@ uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
Mem_Read(add, reg, tx_data, 1);
return tx_data[0];
}
void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size) {
if (I2CSemaphore == NULL) {
// no RToS, run blocking code
HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT,
pData, Size, 5000);
} else {
// RToS is active, run threading
// Get the mutex so we can use the I2C port
// Wait up to 1 second for the mutex
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
#ifdef I2CUSESDMA
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress,
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
if (!lock())
return false;
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress,
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
I2C_Unstick();
xSemaphoreGive(I2CSemaphore);
}
xSemaphoreGive(I2CSemaphore);
#else
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, pData,
Size, 5000) != HAL_OK) {
}
xSemaphoreGive(I2CSemaphore);
#endif
} else {
}
I2C_Unstick();
unlock();
return false;
}
unlock();
return true;
}
void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
if (I2CSemaphore == NULL) {
// no RToS, run blocking code
HAL_I2C_Master_Transmit(&hi2c1, DevAddress, pData, Size, 5000);
} else {
// RToS is active, run threading
// Get the mutex so we can use the I2C port
// Wait up to 1 second for the mutex
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
#ifdef I2CUSESDMA
if (HAL_I2C_Master_Transmit_DMA(&hi2c1, DevAddress, pData, Size)
!= HAL_OK) {
I2C_Unstick();
xSemaphoreGive(I2CSemaphore);
}
#else
HAL_I2C_Master_Transmit(&hi2c1, DevAddress, pData, Size, 5000);
xSemaphoreGive(I2CSemaphore);
#endif
} else {
}
bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
if (!lock())
return false;
if (HAL_I2C_Master_Transmit_DMA(&hi2c1, DevAddress, pData, Size)
!= HAL_OK) {
I2C_Unstick();
unlock();
return false;
}
return true;
}
bool FRToSI2C::probe(uint16_t DevAddress) {
if (!lock())
return false;
uint8_t buffer[1];
if (Mem_Read(DevAddress, 0, buffer, 1)) {
//ACK'd
return true;
}
return false;
bool worked = HAL_I2C_Mem_Read(&hi2c1, DevAddress, 0x0F,
I2C_MEMADD_SIZE_8BIT, buffer, 1, 1000) == HAL_OK;
unlock();
return worked;
}
void FRToSI2C::I2C_Unstick() {
unstick_I2C();
}
void FRToSI2C::unlock() {
xSemaphoreGive(I2CSemaphore);
}
bool FRToSI2C::lock() {
return xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE;
}

View File

@@ -0,0 +1,49 @@
/*
* IRQ.c
*
* Created on: 30 May 2020
* Author: Ralim
*/
#include "IRQ.h"
#include "int_n.h"
/*
* Catch the IRQ that says that the conversion is done on the temperature
* readings coming in Once these have come in we can unblock the PID so that it
* runs again
*/
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (hadc == &hadc1) {
if (pidTaskNotification) {
vTaskNotifyGiveFromISR(pidTaskNotification,
&xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
}
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
(void)GPIO_Pin;
InterruptHandler::irqCallback();
}

View File

@@ -0,0 +1,32 @@
/*
* Irqs.h
*
* Created on: 30 May 2020
* Author: Ralim
*/
#ifndef BSP_MINIWARE_IRQ_H_
#define BSP_MINIWARE_IRQ_H_
#include "BSP.h"
#include "stm32f1xx_hal.h"
#include "I2C_Wrapper.hpp"
#include "Setup.h"
#include "main.hpp"
#ifdef __cplusplus
extern "C" {
#endif
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc);
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_GPIO_EXTI_Callback(uint16_t);
#ifdef __cplusplus
}
#endif
#endif /* BSP_MINIWARE_IRQ_H_ */

View File

@@ -0,0 +1,44 @@
/*
* Model_Config.h
*
* Created on: 25 Jul 2020
* Author: Ralim
*/
#ifndef BSP_MINIWARE_MODEL_CONFIG_H_
#define BSP_MINIWARE_MODEL_CONFIG_H_
/*
* Lookup for mapping features <-> Models
*/
#if defined(MODEL_TS100) + defined(MODEL_TS80)+defined(MODEL_TS80P) > 1
#error "Multiple models defined!"
#elif defined(MODEL_TS100) + defined(MODEL_TS80)+ defined(MODEL_TS80P) == 0
#error "No model defined!"
#endif
#ifdef MODEL_TS100
#define ACCEL_MMA
#define ACCEL_LIS
#define TEMP_TMP36
#endif
#ifdef MODEL_TS80
#define ACCEL_LIS
#define POW_QC
#define TEMP_TMP36
#define LIS_ORI_FLIP
#define OLED_FLIP
#endif
#ifdef MODEL_TS80P
#define ACCEL_LIS
#define POW_PD
#define POW_QC
#define TEMP_NTC
#define I2C_SOFT
#define LIS_ORI_FLIP
#define OLED_FLIP
#endif
#endif /* BSP_MINIWARE_MODEL_CONFIG_H_ */

View File

@@ -7,12 +7,7 @@
#ifndef BSP_MINIWARE_PINS_H_
#define BSP_MINIWARE_PINS_H_
#if defined(MODEL_TS100) + defined(MODEL_TS80) > 1
#error "Multiple models defined!"
#elif defined(MODEL_TS100) + defined(MODEL_TS80) == 0
#error "No model defined!"
#endif
#include "Model_Config.h"
#ifdef MODEL_TS100
@@ -45,8 +40,8 @@
#define SCL_GPIO_Port GPIOB
#define SDA_Pin GPIO_PIN_7
#define SDA_GPIO_Port GPIOB
#else
#endif
#ifdef MODEL_TS80
// TS80 pin map
#define KEY_B_Pin GPIO_PIN_0
#define KEY_B_GPIO_Port GPIOB
@@ -77,6 +72,51 @@
#define SCL_GPIO_Port GPIOB
#define SDA_Pin GPIO_PIN_7
#define SDA_GPIO_Port GPIOB
#define SCL2_Pin GPIO_PIN_5
#define SCL2_GPIO_Port GPIOA
#define SDA2_Pin GPIO_PIN_1
#define SDA2_GPIO_Port GPIOA
#define INT_PD_Pin GPIO_PIN_9
#define INT_PD_GPIO_Port GPIOA
#endif
#ifdef MODEL_TS80P
// TS80P pin map
#define KEY_B_Pin GPIO_PIN_0
#define KEY_B_GPIO_Port GPIOB
#define TMP36_INPUT_Pin GPIO_PIN_4
#define TMP36_INPUT_GPIO_Port GPIOA
#define TMP36_ADC1_CHANNEL ADC_CHANNEL_4
#define TIP_TEMP_Pin GPIO_PIN_3
#define TIP_TEMP_GPIO_Port GPIOA
#define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_3
#define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_3
#define VIN_Pin GPIO_PIN_2
#define VIN_GPIO_Port GPIOA
#define VIN_ADC1_CHANNEL ADC_CHANNEL_2
#define VIN_ADC2_CHANNEL ADC_CHANNEL_2
#define OLED_RESET_Pin GPIO_PIN_15
#define OLED_RESET_GPIO_Port GPIOA
#define KEY_A_Pin GPIO_PIN_1
#define KEY_A_GPIO_Port GPIOB
#define INT_Orientation_Pin GPIO_PIN_4
#define INT_Orientation_GPIO_Port GPIOB
#define PWM_Out_Pin GPIO_PIN_6
#define PWM_Out_GPIO_Port GPIOA
#define PWM_Out_CHANNEL TIM_CHANNEL_1
#define INT_Movement_Pin GPIO_PIN_5
#define INT_Movement_GPIO_Port GPIOB
#define SCL_Pin GPIO_PIN_6
#define SCL_GPIO_Port GPIOB
#define SDA_Pin GPIO_PIN_7
#define SDA_GPIO_Port GPIOB
#define SCL2_Pin GPIO_PIN_5
#define SCL2_GPIO_Port GPIOA
#define SDA2_Pin GPIO_PIN_1
#define SDA2_GPIO_Port GPIOA
#define INT_PD_Pin GPIO_PIN_9
#define INT_PD_GPIO_Port GPIOA
#endif

View File

@@ -2,20 +2,35 @@
#include "BSP_Power.h"
#include "QC3.h"
#include "Settings.h"
void power_probe() {
// If TS80 probe for QC
// If TS100 - noop
#ifdef MODEL_TS80
startQC(systemSettings.voltageDiv);
seekQC((systemSettings.cutoutSetting) ? 120 : 90,
systemSettings.voltageDiv); // this will move the QC output to the preferred voltage to start with
#endif
}
#include "Pins.h"
#include "fusbpd.h"
#include "Model_Config.h"
#include "policy_engine.h"
#include "int_n.h"
bool FUSB302_present = false;
void power_check() {
#ifdef MODEL_TS80
QC_resync();
#ifdef POW_PD
if (FUSB302_present) {
//Cant start QC until either PD works or fails
if (PolicyEngine::setupCompleteOrTimedOut() == false) {
return;
}
if (PolicyEngine::pdHasNegotiated()) {
return;
}
}
#endif
}
#ifdef POW_QC
QC_resync();
#endif
}
uint8_t usb_pd_detect() {
#ifdef POW_PD
FUSB302_present = fusb302_detect();
return FUSB302_present;
#endif
return false;
}

View File

@@ -9,6 +9,8 @@
#include "QC3.h"
#include "Settings.h"
#include "stm32f1xx_hal.h"
#include "Model_Config.h"
#ifdef POW_QC
void QC_DPlusZero_Six() {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); // pull down D+
}
@@ -65,10 +67,10 @@ void QC_Post_Probe_En() {
}
uint8_t QC_DM_PulledDown() { return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET ? 1 : 0; }
#endif
void QC_resync() {
#ifdef MODEL_TS80
#ifdef POW_QC
seekQC((systemSettings.cutoutSetting) ? 120 : 90,
systemSettings.voltageDiv); // Run the QC seek again if we have drifted too much
#endif
}
}

View File

@@ -30,11 +30,15 @@ static void MX_TIM2_Init(void);
static void MX_DMA_Init(void);
static void MX_GPIO_Init(void);
static void MX_ADC2_Init(void);
#define SWD_ENABLE
void Setup_HAL() {
SystemClock_Config();
__HAL_AFIO_REMAP_SWJ_DISABLE()
;
#ifndef SWD_ENABLE
__HAL_AFIO_REMAP_SWJ_DISABLE();
#else
__HAL_AFIO_REMAP_SWJ_NOJTAG();
#endif
MX_GPIO_Init();
MX_DMA_Init();
@@ -244,7 +248,7 @@ static void MX_IWDG_Init(void) {
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_256;
hiwdg.Init.Reload = 100;
#ifndef LOCAL_BUILD
#ifndef SWD_ENABLE
HAL_IWDG_Init(&hiwdg);
#endif
}
@@ -425,8 +429,10 @@ static void MX_GPIO_Init(void) {
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
#ifdef MODEL_TS100
/* Pull USB lines low to disable, pull down debug too*/
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
#ifndef SWD_ENABLE
/* Pull USB and SWD lines low to prevent enumeration attempts and EMI affecting
* the debug core */
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
@@ -434,6 +440,12 @@ static void MX_GPIO_Init(void) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_14, GPIO_PIN_RESET);
#else
/* Make all lines affecting SWD floating to allow debugging */
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
#endif
#else
/* TS80 */
/* Leave USB lines open circuit*/
@@ -458,3 +470,8 @@ static void MX_GPIO_Init(void) {
HAL_Delay(30);
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line){
asm("bkpt");
}
#endif

View File

@@ -0,0 +1,27 @@
/*
* Software_I2C.h
*
* Created on: 25 Jul 2020
* Author: Ralim
*/
#ifndef BSP_MINIWARE_SOFTWARE_I2C_H_
#define BSP_MINIWARE_SOFTWARE_I2C_H_
#include "Model_Config.h"
#include "BSP.h"
#include "stm32f1xx_hal.h"
#ifdef I2C_SOFT
#define SOFT_SCL_HIGH() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_SET)
#define SOFT_SCL_LOW() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_RESET)
#define SOFT_SDA_HIGH() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_SET)
#define SOFT_SDA_LOW() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_RESET)
#define SOFT_SDA_READ() (HAL_GPIO_ReadPin(SDA2_GPIO_Port,SDA2_Pin)==GPIO_PIN_SET?1:0)
#define SOFT_SCL_READ() (HAL_GPIO_ReadPin(SCL2_GPIO_Port,SCL2_Pin)==GPIO_PIN_SET?1:0)
#define SOFT_I2C_DELAY() {for(int xx=0;xx<40;xx++){asm("nop");}}
#endif
#endif /* BSP_MINIWARE_SOFTWARE_I2C_H_ */

View File

@@ -1,18 +0,0 @@
/*
* UnitSettings.h
*
* Created on: 29 May 2020
* Author: Ralim
*/
#ifndef BSP_MINIWARE_UNITSETTINGS_H_
#define BSP_MINIWARE_UNITSETTINGS_H_
//On the TS80, the LIS accel is mounted backwards
#ifdef MODEL_TS80
#define LIS_ORI_FLIP
#endif
#endif /* BSP_MINIWARE_UNITSETTINGS_H_ */

View File

@@ -291,7 +291,7 @@ typedef struct
/** @defgroup RCC_Flag Flags
* Elements values convention: XXXYYYYYb
* - YYYYY : Flag position in the register
* - XXX : Register index
* - X XX : Register index
* - 001: CR register
* - 010: BDCR register
* - 011: CSR register

View File

@@ -1041,32 +1041,32 @@ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_I
/* conversions is forced to 0x00 for alignment over all STM32 devices. */
/* - if scan mode is enabled, injected channels sequence length is set to */
/* parameter "InjectedNbrOfConversion". */
if (hadc->Init.ScanConvMode == ADC_SCAN_DISABLE)
{
if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1)
{
/* Clear the old SQx bits for all injected ranks */
MODIFY_REG(hadc->Instance->JSQR ,
ADC_JSQR_JL |
ADC_JSQR_JSQ4 |
ADC_JSQR_JSQ3 |
ADC_JSQR_JSQ2 |
ADC_JSQR_JSQ1 ,
ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel,
ADC_INJECTED_RANK_1,
0x01U));
}
/* If another injected rank than rank1 was intended to be set, and could */
/* not due to ScanConvMode disabled, error is reported. */
else
{
/* Update ADC state machine to error */
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
tmp_hal_status = HAL_ERROR;
}
}
else
// if (hadc->Init.ScanConvMode == ADC_SCAN_DISABLE)
// {
// if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1)
// {
// /* Clear the old SQx bits for all injected ranks */
// MODIFY_REG(hadc->Instance->JSQR ,
// ADC_JSQR_JL |
// ADC_JSQR_JSQ4 |
// ADC_JSQR_JSQ3 |
// ADC_JSQR_JSQ2 |
// ADC_JSQR_JSQ1 ,
// ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel,
// ADC_INJECTED_RANK_1,
// 0x01U));
// }
// /* If another injected rank than rank1 was intended to be set, and could */
// /* not due to ScanConvMode disabled, error is reported. */
// else
// {
// /* Update ADC state machine to error */
// SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
//
// tmp_hal_status = HAL_ERROR;
// }
// }
// else
{
/* Since injected channels rank conv. order depends on total number of */
/* injected conversions, selected rank must be below or equal to total */

View File

@@ -3479,6 +3479,7 @@ void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
}
}
/* Slave mode selected */
#if 0
else
{
/* ADDR set --------------------------------------------------------------*/
@@ -3520,6 +3521,7 @@ void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
}
}
}
#endif
}
/**

View File

@@ -369,57 +369,6 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
/*------------------------------- HSE Configuration ------------------------*/
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
{
/* Check the parameters */
assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
/* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
|| ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
{
if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
{
return HAL_ERROR;
}
}
else
{
/* Set the new HSE configuration ---------------------------------------*/
__HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
/* Check the HSE State */
if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
{
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till HSE is ready */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
{
if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
else
{
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till HSE is disabled */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
{
if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
}
}
/*----------------------------- HSI Configuration --------------------------*/
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
{
@@ -486,121 +435,9 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
}
}
/*------------------------------ LSI Configuration -------------------------*/
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
{
/* Check the parameters */
assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
/* Check the LSI State */
if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
{
/* Enable the Internal Low Speed oscillator (LSI). */
__HAL_RCC_LSI_ENABLE();
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till LSI is ready */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
{
if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
/* To have a fully stabilized clock in the specified range, a software delay of 1ms
should be added.*/
RCC_Delay(1);
}
else
{
/* Disable the Internal Low Speed oscillator (LSI). */
__HAL_RCC_LSI_DISABLE();
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till LSI is disabled */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
{
if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
}
/*------------------------------ LSE Configuration -------------------------*/
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
{
FlagStatus pwrclkchanged = RESET;
/* Check the parameters */
assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
/* Update LSE configuration in Backup Domain control register */
/* Requires to enable write access to Backup Domain of necessary */
if(__HAL_RCC_PWR_IS_CLK_DISABLED())
{
__HAL_RCC_PWR_CLK_ENABLE();
pwrclkchanged = SET;
}
if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
{
/* Enable write access to Backup domain */
SET_BIT(PWR->CR, PWR_CR_DBP);
/* Wait for Backup domain Write protection disable */
tickstart = HAL_GetTick();
while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
{
if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
/* Set the new LSE configuration -----------------------------------------*/
__HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
/* Check the LSE State */
if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
{
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till LSE is ready */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
{
if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
else
{
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till LSE is disabled */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
{
if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
/* Require to disable power clock if necessary */
if(pwrclkchanged == SET)
{
__HAL_RCC_PWR_CLK_DISABLE();
}
}
#if defined(RCC_CR_PLL2ON)
/*-------------------------------- PLL2 Configuration -----------------------*/

View File

@@ -3968,129 +3968,129 @@ HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, TIM_ClockCo
}
break;
case TIM_CLOCKSOURCE_ETRMODE1:
{
/* Check whether or not the timer instance supports external trigger input mode 1 (ETRF)*/
assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance));
/* Check ETR input conditioning related parameters */
assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
/* Configure the ETR Clock source */
TIM_ETR_SetConfig(htim->Instance,
sClockSourceConfig->ClockPrescaler,
sClockSourceConfig->ClockPolarity,
sClockSourceConfig->ClockFilter);
/* Get the TIMx SMCR register value */
tmpsmcr = htim->Instance->SMCR;
/* Reset the SMS and TS Bits */
tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS);
/* Select the External clock mode1 and the ETRF trigger */
tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1);
/* Write to TIMx SMCR */
htim->Instance->SMCR = tmpsmcr;
}
break;
case TIM_CLOCKSOURCE_ETRMODE2:
{
/* Check whether or not the timer instance supports external trigger input mode 2 (ETRF)*/
assert_param(IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(htim->Instance));
/* Check ETR input conditioning related parameters */
assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
/* Configure the ETR Clock source */
TIM_ETR_SetConfig(htim->Instance,
sClockSourceConfig->ClockPrescaler,
sClockSourceConfig->ClockPolarity,
sClockSourceConfig->ClockFilter);
/* Enable the External clock mode2 */
htim->Instance->SMCR |= TIM_SMCR_ECE;
}
break;
case TIM_CLOCKSOURCE_TI1:
{
/* Check whether or not the timer instance supports external clock mode 1 */
assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
/* Check TI1 input conditioning related parameters */
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
TIM_TI1_ConfigInputStage(htim->Instance,
sClockSourceConfig->ClockPolarity,
sClockSourceConfig->ClockFilter);
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1);
}
break;
case TIM_CLOCKSOURCE_TI2:
{
/* Check whether or not the timer instance supports external clock mode 1 (ETRF)*/
assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
/* Check TI2 input conditioning related parameters */
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
TIM_TI2_ConfigInputStage(htim->Instance,
sClockSourceConfig->ClockPolarity,
sClockSourceConfig->ClockFilter);
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2);
}
break;
case TIM_CLOCKSOURCE_TI1ED:
{
/* Check whether or not the timer instance supports external clock mode 1 */
assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
/* Check TI1 input conditioning related parameters */
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
TIM_TI1_ConfigInputStage(htim->Instance,
sClockSourceConfig->ClockPolarity,
sClockSourceConfig->ClockFilter);
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED);
}
break;
case TIM_CLOCKSOURCE_ITR0:
{
/* Check whether or not the timer instance supports external clock mode 1 */
assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR0);
}
break;
case TIM_CLOCKSOURCE_ITR1:
{
/* Check whether or not the timer instance supports external clock mode 1 */
assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR1);
}
break;
case TIM_CLOCKSOURCE_ITR2:
{
/* Check whether or not the timer instance supports external clock mode 1 */
assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR2);
}
break;
case TIM_CLOCKSOURCE_ITR3:
{
/* Check whether or not the timer instance supports external clock mode 1 */
assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR3);
}
break;
// case TIM_CLOCKSOURCE_ETRMODE1:
// {
// /* Check whether or not the timer instance supports external trigger input mode 1 (ETRF)*/
// assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance));
//
// /* Check ETR input conditioning related parameters */
// assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
// assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
// assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
//
// /* Configure the ETR Clock source */
// TIM_ETR_SetConfig(htim->Instance,
// sClockSourceConfig->ClockPrescaler,
// sClockSourceConfig->ClockPolarity,
// sClockSourceConfig->ClockFilter);
// /* Get the TIMx SMCR register value */
// tmpsmcr = htim->Instance->SMCR;
// /* Reset the SMS and TS Bits */
// tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS);
// /* Select the External clock mode1 and the ETRF trigger */
// tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1);
// /* Write to TIMx SMCR */
// htim->Instance->SMCR = tmpsmcr;
// }
// break;
//
// case TIM_CLOCKSOURCE_ETRMODE2:
// {
// /* Check whether or not the timer instance supports external trigger input mode 2 (ETRF)*/
// assert_param(IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(htim->Instance));
//
// /* Check ETR input conditioning related parameters */
// assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
// assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
// assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
//
// /* Configure the ETR Clock source */
// TIM_ETR_SetConfig(htim->Instance,
// sClockSourceConfig->ClockPrescaler,
// sClockSourceConfig->ClockPolarity,
// sClockSourceConfig->ClockFilter);
// /* Enable the External clock mode2 */
// htim->Instance->SMCR |= TIM_SMCR_ECE;
// }
// break;
//
// case TIM_CLOCKSOURCE_TI1:
// {
// /* Check whether or not the timer instance supports external clock mode 1 */
// assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
//
// /* Check TI1 input conditioning related parameters */
// assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
// assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
//
// TIM_TI1_ConfigInputStage(htim->Instance,
// sClockSourceConfig->ClockPolarity,
// sClockSourceConfig->ClockFilter);
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1);
// }
// break;
// case TIM_CLOCKSOURCE_TI2:
// {
// /* Check whether or not the timer instance supports external clock mode 1 (ETRF)*/
// assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
//
// /* Check TI2 input conditioning related parameters */
// assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
// assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
//
// TIM_TI2_ConfigInputStage(htim->Instance,
// sClockSourceConfig->ClockPolarity,
// sClockSourceConfig->ClockFilter);
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2);
// }
// break;
// case TIM_CLOCKSOURCE_TI1ED:
// {
// /* Check whether or not the timer instance supports external clock mode 1 */
// assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
//
// /* Check TI1 input conditioning related parameters */
// assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
// assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
//
// TIM_TI1_ConfigInputStage(htim->Instance,
// sClockSourceConfig->ClockPolarity,
// sClockSourceConfig->ClockFilter);
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED);
// }
// break;
// case TIM_CLOCKSOURCE_ITR0:
// {
// /* Check whether or not the timer instance supports external clock mode 1 */
// assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
//
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR0);
// }
// break;
// case TIM_CLOCKSOURCE_ITR1:
// {
// /* Check whether or not the timer instance supports external clock mode 1 */
// assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
//
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR1);
// }
// break;
// case TIM_CLOCKSOURCE_ITR2:
// {
// /* Check whether or not the timer instance supports external clock mode 1 */
// assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
//
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR2);
// }
// break;
// case TIM_CLOCKSOURCE_ITR3:
// {
// /* Check whether or not the timer instance supports external clock mode 1 */
// assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
//
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR3);
// }
// break;
default:
break;

View File

@@ -9,21 +9,21 @@
#include "BSP.h"
#include "string.h"
#include "stm32f1xx_hal.h"
/*Flash start OR'ed with the maximum amount of flash - 1024 bytes*/
/*We use the last 1024 byte page*/
#define FLASH_ADDR (0x8000000 |0xFC00)
static uint16_t settings_page[512] __attribute__ ((section (".settings_page")));
uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
FLASH_EraseInitTypeDef pEraseInit;
pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
pEraseInit.Banks = FLASH_BANK_1;
pEraseInit.NbPages = 1;
pEraseInit.PageAddress = FLASH_ADDR;
pEraseInit.PageAddress = (uint32_t)settings_page;
uint32_t failingAddress = 0;
resetWatchdog();
__HAL_FLASH_CLEAR_FLAG(
FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_BSY);
HAL_FLASH_Unlock();
HAL_Delay(10);
HAL_Delay(1);
resetWatchdog();
HAL_FLASHEx_Erase(&pEraseInit, &failingAddress);
//^ Erase the page of flash (1024 bytes on this stm32)
@@ -33,7 +33,7 @@ uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
HAL_FLASH_Unlock();
for (uint8_t i = 0; i < (length / 2); i++) {
resetWatchdog();
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FLASH_ADDR + (i * 2),
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)&settings_page[i],
data[i]);
}
HAL_FLASH_Lock();
@@ -42,8 +42,5 @@ uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
void flash_read_buffer(uint8_t *buffer, const uint16_t length) {
uint16_t *data = (uint16_t*) buffer;
for (uint8_t i = 0; i < (length / 2); i++) {
data[i] = *((uint16_t*) (FLASH_ADDR + (i * 2)));
}
memcpy(buffer, settings_page, length);
}

View File

@@ -0,0 +1,266 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Model_Config.h"
#ifdef POW_PD
#include "BSP.h"
#include "fusb302b.h"
#include "I2CBB.hpp"
#include <pd.h>
#include "int_n.h"
/*
* Read a single byte from the FUSB302B
*
* cfg: The FUSB302B to communicate with
* addr: The memory address from which to read
*
* Returns the value read from addr.
*/
static uint8_t fusb_read_byte(uint8_t addr) {
uint8_t data[1];
if (!I2CBB::Mem_Read(FUSB302B_ADDR, addr, (uint8_t*) data, 1)) {
return 0;
}
return data[0];
}
/*
* Read multiple bytes from the FUSB302B
*
* cfg: The FUSB302B to communicate with
* addr: The memory address from which to read
* size: The number of bytes to read
* buf: The buffer into which data will be read
*/
static bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf) {
return I2CBB::Mem_Read(FUSB302B_ADDR, addr, buf, size);
}
/*
* Write a single byte to the FUSB302B
*
* cfg: The FUSB302B to communicate with
* addr: The memory address to which we will write
* byte: The value to write
*/
static bool fusb_write_byte(uint8_t addr, uint8_t byte) {
return I2CBB::Mem_Write(FUSB302B_ADDR, addr, (uint8_t*) &byte, 1);
}
/*
* Write multiple bytes to the FUSB302B
*
* cfg: The FUSB302B to communicate with
* addr: The memory address to which we will write
* size: The number of bytes to write
* buf: The buffer to write
*/
static bool fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf) {
return I2CBB::Mem_Write(FUSB302B_ADDR, addr, buf, size);
}
void fusb_send_message(const union pd_msg *msg) {
if (!I2CBB::lock2()) {
return;
}
/* Token sequences for the FUSB302B */
static uint8_t sop_seq[5] = {
FUSB_FIFO_TX_SOP1,
FUSB_FIFO_TX_SOP1,
FUSB_FIFO_TX_SOP1,
FUSB_FIFO_TX_SOP2,
FUSB_FIFO_TX_PACKSYM };
static const uint8_t eop_seq[4] = {
FUSB_FIFO_TX_JAM_CRC,
FUSB_FIFO_TX_EOP,
FUSB_FIFO_TX_TXOFF,
FUSB_FIFO_TX_TXON };
/* Take the I2C2 mutex now so there can't be a race condition on sop_seq */
/* Get the length of the message: a two-octet header plus NUMOBJ four-octet
* data objects */
uint8_t msg_len = 2 + 4 * PD_NUMOBJ_GET(msg);
/* Set the number of bytes to be transmitted in the packet */
sop_seq[4] = FUSB_FIFO_TX_PACKSYM | msg_len;
/* Write all three parts of the message to the TX FIFO */
fusb_write_buf( FUSB_FIFOS, 5, sop_seq);
fusb_write_buf( FUSB_FIFOS, msg_len, msg->bytes);
fusb_write_buf( FUSB_FIFOS, 4, eop_seq);
I2CBB::unlock2();
}
uint8_t fusb_read_message(union pd_msg *msg) {
if (!I2CBB::lock2()) {
asm("bkpt");
}
static uint8_t garbage[4];
uint8_t numobj;
// Read the header. If its not a SOP we dont actually want it at all
// But on some revisions of the fusb if you dont both pick them up and read them out of the fifo, it gets stuck
fusb_read_byte( FUSB_FIFOS);
/* Read the message header into msg */
fusb_read_buf( FUSB_FIFOS, 2, msg->bytes);
/* Get the number of data objects */
numobj = PD_NUMOBJ_GET(msg);
/* If there is at least one data object, read the data objects */
if (numobj > 0) {
fusb_read_buf( FUSB_FIFOS, numobj * 4, msg->bytes + 2);
}
/* Throw the CRC32 in the garbage, since the PHY already checked it. */
fusb_read_buf( FUSB_FIFOS, 4, garbage);
I2CBB::unlock2();
return 0;
}
void fusb_send_hardrst() {
if (!I2CBB::lock2()) {
return;
}
/* Send a hard reset */
fusb_write_byte( FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET);
I2CBB::unlock2();
}
void fusb_setup() {
if (!I2CBB::lock2()) {
return;
}
/* Fully reset the FUSB302B */
// fusb_write_byte( FUSB_RESET, FUSB_RESET_SW_RES);
// osDelay(2);
if (!fusb_read_id()) {
return;
}
/* Turn on all power */
fusb_write_byte( FUSB_POWER, 0x0F);
/* Set interrupt masks */
//Setting to 0 so interrupts are allowed
fusb_write_byte( FUSB_MASK1, 0x00);
fusb_write_byte( FUSB_MASKA, 0x00);
fusb_write_byte( FUSB_MASKB, 0x00);
fusb_write_byte( FUSB_CONTROL0, 0b11 << 2);
/* Enable automatic retransmission */
fusb_write_byte( FUSB_CONTROL3, 0x07);
//set defaults
fusb_write_byte( FUSB_CONTROL2, 0x00);
/* Flush the RX buffer */
fusb_write_byte( FUSB_CONTROL1,
FUSB_CONTROL1_RX_FLUSH);
/* Measure CC1 */
fusb_write_byte( FUSB_SWITCHES0, 0x07);
osDelay(10);
uint8_t cc1 = fusb_read_byte( FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
/* Measure CC2 */
fusb_write_byte( FUSB_SWITCHES0, 0x0B);
osDelay(10);
uint8_t cc2 = fusb_read_byte( FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
/* Select the correct CC line for BMC signaling; also enable AUTO_CRC */
if (cc1 > cc2) {
fusb_write_byte( FUSB_SWITCHES1, 0x25);
fusb_write_byte( FUSB_SWITCHES0, 0x07);
} else {
fusb_write_byte( FUSB_SWITCHES1, 0x26);
fusb_write_byte( FUSB_SWITCHES0, 0x0B);
}
I2CBB::unlock2();
fusb_reset();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
}
void fusb_get_status(union fusb_status *status) {
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
if (!I2CBB::lock2()) {
return;
}
}
/* Read the interrupt and status flags into status */
fusb_read_buf( FUSB_STATUS0A, 7, status->bytes);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
I2CBB::unlock2();
}
}
enum fusb_typec_current fusb_get_typec_current() {
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
if (!I2CBB::lock2()) {
return fusb_tcc_none;
}
}
/* Read the BC_LVL into a variable */
enum fusb_typec_current bc_lvl = (enum fusb_typec_current) (fusb_read_byte(
FUSB_STATUS0) & FUSB_STATUS0_BC_LVL);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
I2CBB::unlock2();
}
return bc_lvl;
}
void fusb_reset() {
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
if (!I2CBB::lock2()) {
return;
}
}
/* Flush the TX buffer */
fusb_write_byte( FUSB_CONTROL0, 0x44);
/* Flush the RX buffer */
fusb_write_byte( FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
/* Reset the PD logic */
// fusb_write_byte( FUSB_RESET, FUSB_RESET_PD_RESET);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
I2CBB::unlock2();
}
}
bool fusb_read_id() {
//Return true if read of the revision ID is sane
uint8_t version = 0;
fusb_read_buf(FUSB_DEVICE_ID, 1, &version);
if (version == 0 || version == 0xFF)
return false;
return true;
}
uint8_t fusb302_detect() {
//Probe the I2C bus for its address
return I2CBB::probe(FUSB302B_ADDR);
}
#endif

View File

@@ -7,8 +7,8 @@
#include "BSP.h"
#include "OLED.hpp"
// Second last page of flash set aside for logo image.
#define FLASH_LOGOADDR (0x8000000 | 0xF800)
static uint8_t logo_page[1024] __attribute__ ((section (".logo_page")));
// Logo header signature.
#define LOGO_HEADER_VALUE 0xF00DAA55
@@ -16,11 +16,11 @@
uint8_t showBootLogoIfavailable() {
// Do not show logo data if signature is not found.
if (LOGO_HEADER_VALUE
!= *(reinterpret_cast<const uint32_t*>(FLASH_LOGOADDR))) {
!= *(reinterpret_cast<const uint32_t*>(logo_page))) {
return 0;
}
OLED::drawAreaSwapped(0, 0, 96, 16, (uint8_t*) (FLASH_LOGOADDR + 4));
OLED::drawAreaSwapped(0, 0, 96, 16, (uint8_t*) (logo_page + 4));
OLED::refresh();
return 1;
}

View File

@@ -7,7 +7,15 @@
#include "power.hpp"
#include "stdlib.h"
#include "task.h"
#include "I2C_Wrapper.hpp"
#include "fusbpd.h"
// Initialisation to be performed with scheduler active
void postRToSInit() {
// Any after RTos setup
#ifdef POW_PD
if (usb_pd_detect() == true) {
//Spawn all of the USB-C processors
fusb302_start_processing();
}
#endif
}

View File

@@ -9,14 +9,17 @@
#include "BSP.h"
#include "Setup.h"
#include "Pins.h"
#include "I2CBB.hpp"
#include "fusbpd.h"
#include "Model_Config.h"
void preRToSInit() {
/* Reset of all peripherals, Initializes the Flash interface and the Systick.
*/
HAL_Init();
Setup_HAL(); // Setup all the HAL objects
FRToSI2C::init();
HAL_Delay(50);
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
HAL_Delay(50);
#ifdef I2C_SOFT
I2CBB::init();
#endif
/* Init the IPC objects */
FRToSI2C::FRToSInit();
}

View File

@@ -82,3 +82,6 @@ void DMA1_Channel6_IRQHandler(void) {
void DMA1_Channel7_IRQHandler(void) {
HAL_DMA_IRQHandler(&hdma_i2c1_rx);
}
void EXTI9_5_IRQHandler(void){
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
}

View File

@@ -11,15 +11,13 @@
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
/* #define DATA_IN_ExtSRAM */
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
#ifndef LOCAL_BUILD
#ifndef VECT_TAB_OFFSET
#define VECT_TAB_OFFSET 0x00004000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#else
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#warning LOCAL_BUILD SETUP
#endif
//We offset this by 0x4000 to because of the bootloader
#endif
/*******************************************************************************
* Clock Definitions
*******************************************************************************/

View File

@@ -24,7 +24,7 @@ ButtonState getButtonState() {
*/
static uint8_t previousState = 0;
static uint32_t previousStateChange = 0;
const uint16_t timeout = 40;
const uint16_t timeout = 400;
uint8_t currentState;
currentState = (getButtonA()) << 0;
currentState |= (getButtonB()) << 1;

View File

@@ -0,0 +1,305 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PDB_FUSB302B_H
#define PDB_FUSB302B_H
#include <stdint.h>
#include "pd.h"
#include <pdb_msg.h>
/* I2C addresses of the FUSB302B chips */
#define FUSB302B_ADDR (0x22<<1)
#define FUSB302B01_ADDR (0x23<<1)
#define FUSB302B10_ADDR (0x24<<1)
#define FUSB302B11_ADDR (0x25<<1)
/* Device ID register */
#define FUSB_DEVICE_ID 0x01
#define FUSB_DEVICE_ID_VERSION_ID_SHIFT 4
#define FUSB_DEVICE_ID_VERSION_ID (0xF << FUSB_DEVICE_ID_VERSION_ID_SHIFT)
#define FUSB_DEVICE_ID_PRODUCT_ID_SHIFT 2
#define FUSB_DEVICE_ID_PRODUCT_ID (0x3 << FUSB_DEVICE_ID_PRODUCT_ID_SHIFT)
#define FUSB_DEVICE_ID_REVISION_ID_SHIFT 0
#define FUSB_DEVICE_ID_REVISION_ID (0x3 << FUSB_DEVICE_ID_REVISION_ID_SHIFT)
/* Switches0 register */
#define FUSB_SWITCHES0 0x02
#define FUSB_SWITCHES0_PU_EN2 (1 << 7)
#define FUSB_SWITCHES0_PU_EN1 (1 << 6)
#define FUSB_SWITCHES0_VCONN_CC2 (1 << 5)
#define FUSB_SWITCHES0_VCONN_CC1 (1 << 4)
#define FUSB_SWITCHES0_MEAS_CC2 (1 << 3)
#define FUSB_SWITCHES0_MEAS_CC1 (1 << 2)
#define FUSB_SWITCHES0_PDWN_2 (1 << 1)
#define FUSB_SWITCHES0_PDWN_1 1
/* Switches1 register */
#define FUSB_SWITCHES1 0x03
#define FUSB_SWITCHES1_POWERROLE (1 << 7)
#define FUSB_SWITCHES1_SPECREV_SHIFT 5
#define FUSB_SWITCHES1_SPECREV (0x3 << FUSB_SWITCHES1_SPECREV_SHIFT)
#define FUSB_SWITCHES1_DATAROLE (1 << 4)
#define FUSB_SWITCHES1_AUTO_CRC (1 << 2)
#define FUSB_SWITCHES1_TXCC2 (1 << 1)
#define FUSB_SWITCHES1_TXCC1 1
/* Measure register */
#define FUSB_MEASURE 0x04
#define FUSB_MEASURE_MEAS_VBUS (1 << 6)
#define FUSB_MEASURE_MDAC_SHIFT 0
#define FUSB_MEASURE_MDAC (0x3F << FUSB_MEASURE_MDAC_SHIFT)
/* Slice register */
#define FUSB_SLICE 0x05
#define FUSB_SLICE_SDAC_HYS_SHIFT 6
#define FUSB_SLICE_SDAC_HYS (0x3 << FUSB_SLICE_SDAC_HYS_SHIFT)
#define FUSB_SLICE_SDAC_SHIFT 0
#define FUSB_SLICE_SDAC (0x3F << FUSB_SLICE_SDAC_SHIFT)
/* Control0 register */
#define FUSB_CONTROL0 0x06
#define FUSB_CONTROL0_TX_FLUSH (1 << 6)
#define FUSB_CONTROL0_INT_MASK (1 << 5)
#define FUSB_CONTROL0_HOST_CUR_SHIFT 2
#define FUSB_CONTROL0_HOST_CUR (0x3 << FUSB_CONTROL0_HOST_CUR_SHIFT)
#define FUSB_CONTROL0_AUTO_PRE (1 << 1)
#define FUSB_CONTROL0_TX_START 1
/* Control1 register */
#define FUSB_CONTROL1 0x07
#define FUSB_CONTROL1_ENSOP2DB (1 << 6)
#define FUSB_CONTROL1_ENSOP1DB (1 << 5)
#define FUSB_CONTROL1_BIST_MODE2 (1 << 4)
#define FUSB_CONTROL1_RX_FLUSH (1 << 2)
#define FUSB_CONTROL1_ENSOP2 (1 << 1)
#define FUSB_CONTROL1_ENSOP1 1
/* Control2 register */
#define FUSB_CONTROL2 0x08
#define FUSB_CONTROL2_TOG_SAVE_PWR_SHIFT 6
#define FUSB_CONTROL2_TOG_SAVE_PWR (0x3 << FUSB_CONTROL2_TOG_SAVE_PWR)
#define FUSB_CONTROL2_TOG_RD_ONLY (1 << 5)
#define FUSB_CONTROL2_WAKE_EN (1 << 3)
#define FUSB_CONTROL2_MODE_SHIFT 1
#define FUSB_CONTROL2_MODE (0x3 << FUSB_CONTROL2_MODE_SHIFT)
#define FUSB_CONTROL2_TOGGLE 1
/* Control3 register */
#define FUSB_CONTROL3 0x09
#define FUSB_CONTROL3_SEND_HARD_RESET (1 << 6)
#define FUSB_CONTROL3_BIST_TMODE (1 << 5)
#define FUSB_CONTROL3_AUTO_HARDRESET (1 << 4)
#define FUSB_CONTROL3_AUTO_SOFTRESET (1 << 3)
#define FUSB_CONTROL3_N_RETRIES_SHIFT 1
#define FUSB_CONTROL3_N_RETRIES (0x3 << FUSB_CONTROL3_N_RETRIES_SHIFT)
#define FUSB_CONTROL3_AUTO_RETRY 1
/* Mask1 register */
#define FUSB_MASK1 0x0A
#define FUSB_MASK1_M_VBUSOK (1 << 7)
#define FUSB_MASK1_M_ACTIVITY (1 << 6)
#define FUSB_MASK1_M_COMP_CHNG (1 << 5)
#define FUSB_MASK1_M_CRC_CHK (1 << 4)
#define FUSB_MASK1_M_ALERT (1 << 3)
#define FUSB_MASK1_M_WAKE (1 << 2)
#define FUSB_MASK1_M_COLLISION (1 << 1)
#define FUSB_MASK1_M_BC_LVL (1 << 0)
/* Power register */
#define FUSB_POWER 0x0B
#define FUSB_POWER_PWR3 (1 << 3)
#define FUSB_POWER_PWR2 (1 << 2)
#define FUSB_POWER_PWR1 (1 << 1)
#define FUSB_POWER_PWR0 1
/* Reset register */
#define FUSB_RESET 0x0C
#define FUSB_RESET_PD_RESET (1 << 1)
#define FUSB_RESET_SW_RES 1
/* OCPreg register */
#define FUSB_OCPREG 0x0D
#define FUSB_OCPREG_OCP_RANGE (1 << 3)
#define FUSB_OCPREG_OCP_CUR_SHIFT 0
#define FUSB_OCPREG_OCP_CUR (0x7 << FUSB_OCPREG_OCP_CUR_SHIFT)
/* Maska register */
#define FUSB_MASKA 0x0E
#define FUSB_MASKA_M_OCP_TEMP (1 << 7)
#define FUSB_MASKA_M_TOGDONE (1 << 6)
#define FUSB_MASKA_M_SOFTFAIL (1 << 5)
#define FUSB_MASKA_M_RETRYFAIL (1 << 4)
#define FUSB_MASKA_M_HARDSENT (1 << 3)
#define FUSB_MASKA_M_TXSENT (1 << 2)
#define FUSB_MASKA_M_SOFTRST (1 << 1)
#define FUSB_MASKA_M_HARDRST 1
/* Maskb register */
#define FUSB_MASKB 0x0F
#define FUSB_MASKB_M_GCRCSENT 1
/* Control4 register */
#define FUSB_CONTROL4 0x10
#define FUSB_CONTROL4_TOG_EXIT_AUD 1
/* Status0a register */
#define FUSB_STATUS0A 0x3C
#define FUSB_STATUS0A_SOFTFAIL (1 << 5)
#define FUSB_STATUS0A_RETRYFAIL (1 << 4)
#define FUSB_STATUS0A_POWER3 (1 << 3)
#define FUSB_STATUS0A_POWER2 (1 << 2)
#define FUSB_STATUS0A_SOFTRST (1 << 1)
#define FUSB_STATUS0A_HARDRST 1
/* Status1a register */
#define FUSB_STATUS1A 0x3D
#define FUSB_STATUS1A_TOGSS_SHIFT 3
#define FUSB_STATUS1A_TOGSS (0x7 << FUSB_STATUS1A_TOGSS_SHIFT)
#define FUSB_STATUS1A_RXSOP2DB (1 << 2)
#define FUSB_STATUS1A_RXSOP1DB (1 << 1)
#define FUSB_STATUS1A_RXSOP 1
/* Interrupta register */
#define FUSB_INTERRUPTA 0x3E
#define FUSB_INTERRUPTA_I_OCP_TEMP (1 << 7)
#define FUSB_INTERRUPTA_I_TOGDONE (1 << 6)
#define FUSB_INTERRUPTA_I_SOFTFAIL (1 << 5)
#define FUSB_INTERRUPTA_I_RETRYFAIL (1 << 4)
#define FUSB_INTERRUPTA_I_HARDSENT (1 << 3)
#define FUSB_INTERRUPTA_I_TXSENT (1 << 2)
#define FUSB_INTERRUPTA_I_SOFTRST (1 << 1)
#define FUSB_INTERRUPTA_I_HARDRST 1
/* Interruptb register */
#define FUSB_INTERRUPTB 0x3F
#define FUSB_INTERRUPTB_I_GCRCSENT 1
/* Status0 register */
#define FUSB_STATUS0 0x40
#define FUSB_STATUS0_VBUSOK (1 << 7)
#define FUSB_STATUS0_ACTIVITY (1 << 6)
#define FUSB_STATUS0_COMP (1 << 5)
#define FUSB_STATUS0_CRC_CHK (1 << 4)
#define FUSB_STATUS0_ALERT (1 << 3)
#define FUSB_STATUS0_WAKE (1 << 2)
#define FUSB_STATUS0_BC_LVL_SHIFT 0
#define FUSB_STATUS0_BC_LVL (0x3 << FUSB_STATUS0_BC_LVL_SHIFT)
/* Status1 register */
#define FUSB_STATUS1 0x41
#define FUSB_STATUS1_RXSOP2 (1 << 7)
#define FUSB_STATUS1_RXSOP1 (1 << 6)
#define FUSB_STATUS1_RX_EMPTY (1 << 5)
#define FUSB_STATUS1_RX_FULL (1 << 4)
#define FUSB_STATUS1_TX_EMPTY (1 << 3)
#define FUSB_STATUS1_TX_FULL (1 << 2)
#define FUSB_STATUS1_OVRTEMP (1 << 1)
#define FUSB_STATUS1_OCP 1
/* Interrupt register */
#define FUSB_INTERRUPT 0x42
#define FUSB_INTERRUPT_I_VBUSOK (1 << 7)
#define FUSB_INTERRUPT_I_ACTIVITY (1 << 6)
#define FUSB_INTERRUPT_I_COMP_CHNG (1 << 5)
#define FUSB_INTERRUPT_I_CRC_CHK (1 << 4)
#define FUSB_INTERRUPT_I_ALERT (1 << 3)
#define FUSB_INTERRUPT_I_WAKE (1 << 2)
#define FUSB_INTERRUPT_I_COLLISION (1 << 1)
#define FUSB_INTERRUPT_I_BC_LVL 1
/* FIFOs register */
#define FUSB_FIFOS 0x43
#define FUSB_FIFO_TX_TXON 0xA1
#define FUSB_FIFO_TX_SOP1 0x12
#define FUSB_FIFO_TX_SOP2 0x13
#define FUSB_FIFO_TX_SOP3 0x1B
#define FUSB_FIFO_TX_RESET1 0x15
#define FUSB_FIFO_TX_RESET2 0x16
#define FUSB_FIFO_TX_PACKSYM 0x80
#define FUSB_FIFO_TX_JAM_CRC 0xFF
#define FUSB_FIFO_TX_EOP 0x14
#define FUSB_FIFO_TX_TXOFF 0xFE
#define FUSB_FIFO_RX_TOKEN_BITS 0xE0
#define FUSB_FIFO_RX_SOP 0xE0
#define FUSB_FIFO_RX_SOP1 0xC0
#define FUSB_FIFO_RX_SOP2 0xA0
#define FUSB_FIFO_RX_SOP1DB 0x80
#define FUSB_FIFO_RX_SOP2DB 0x60
/*
* FUSB status union
*
* Provides a nicer structure than just an array of uint8_t for working with
* the FUSB302B status and interrupt flags.
*/
union fusb_status {
uint8_t bytes[7];
struct {
uint8_t status0a;
uint8_t status1a;
uint8_t interrupta;
uint8_t interruptb;
uint8_t status0;
uint8_t status1;
uint8_t interrupt;
};
};
/* FUSB functions */
/*
* Send a USB Power Delivery message to the FUSB302B
*/
void fusb_send_message(const union pd_msg *msg);
/*
* Read a USB Power Delivery message from the FUSB302B
*/
uint8_t fusb_read_message(union pd_msg *msg);
/*
* Tell the FUSB302B to send a hard reset signal
*/
void fusb_send_hardrst();
/*
* Read the FUSB302B status and interrupt flags into *status
*/
void fusb_get_status(union fusb_status *status);
/*
* Read the FUSB302B BC_LVL as an enum fusb_typec_current
*/
enum fusb_typec_current fusb_get_typec_current();
/*
* Initialization routine for the FUSB302B
*/
void fusb_setup();
/*
* Reset the FUSB302B
*/
void fusb_reset();
bool fusb_read_id();
#endif /* PDB_FUSB302B_H */

View File

@@ -0,0 +1,27 @@
/*
* fusbpd.cpp
*
* Created on: 13 Jun 2020
* Author: Ralim
*/
#include "Model_Config.h"
#ifdef POW_PD
#include <fusbpd.h>
#include <pd.h>
#include "BSP.h"
#include "I2CBB.hpp"
#include "fusb302b.h"
#include "policy_engine.h"
#include "protocol_rx.h"
#include "protocol_tx.h"
#include "int_n.h"
void fusb302_start_processing() {
/* Initialize the FUSB302B */
fusb_setup();
PolicyEngine::init();
ProtocolTransmit::init();
ProtocolReceive::init();
InterruptHandler::init();
}
#endif

View File

@@ -0,0 +1,18 @@
/*
* fusbpd.h
*
* Created on: 13 Jun 2020
* Author: Ralim
*/
#ifndef DRIVERS_FUSB302_FUSBPD_H_
#define DRIVERS_FUSB302_FUSBPD_H_
//Wrapper for all of the FUSB302 PD work
extern struct pdb_config pdb_config_data;
#include <stdint.h>
//returns 1 if the FUSB302 is on the I2C bus
uint8_t fusb302_detect();
void fusb302_start_processing();
#endif /* DRIVERS_FUSB302_FUSBPD_H_ */

View File

@@ -0,0 +1,84 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "int_n.h"
#include "fusbpd.h"
#include <pd.h>
#include "fusb302b.h"
#include "protocol_rx.h"
#include "protocol_tx.h"
#include "policy_engine.h"
#include "protocol_rx.h"
#include "protocol_tx.h"
#include "task.h"
#include "BSP.h"
osThreadId InterruptHandler::TaskHandle = NULL;
uint32_t InterruptHandler::TaskBuffer[InterruptHandler::TaskStackSize];
osStaticThreadDef_t InterruptHandler::TaskControlBlock;
void InterruptHandler::init() {
osThreadStaticDef(intTask, Thread, PDB_PRIO_PRL_INT_N, 0, TaskStackSize,
TaskBuffer, &TaskControlBlock);
TaskHandle = osThreadCreate(osThread(intTask), NULL);
}
void InterruptHandler::Thread(const void *arg) {
(void) arg;
union fusb_status status;
while (true) {
/* If the INT_N line is low */
if (xTaskNotifyWait(0x00, 0x0F, NULL,
PolicyEngine::setupCompleteOrTimedOut() ? 1000 : 10) == pdPASS) {
//delay slightly so we catch the crc with better timing
osDelay(1);
}
/* Read the FUSB302B status and interrupt registers */
fusb_get_status(&status);
/* If the I_TXSENT or I_RETRYFAIL flag is set, tell the Protocol TX
* thread */
if (status.interrupta & FUSB_INTERRUPTA_I_TXSENT) {
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_TXSENT);
}
if (status.interrupta & FUSB_INTERRUPTA_I_RETRYFAIL) {
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_RETRYFAIL);
}
/* If the I_GCRCSENT flag is set, tell the Protocol RX thread */
//This means a message was recieved with a good CRC
if (status.interruptb & FUSB_INTERRUPTB_I_GCRCSENT) {
ProtocolReceive::notify(PDB_EVT_PRLRX_I_GCRCSENT);
}
/* If the I_OCP_TEMP and OVRTEMP flags are set, tell the Policy
* Engine thread */
if (status.interrupta & FUSB_INTERRUPTA_I_OCP_TEMP
&& status.status1 & FUSB_STATUS1_OVRTEMP) {
PolicyEngine::notify(PDB_EVT_PE_I_OVRTEMP);
}
}
}
void InterruptHandler::irqCallback() {
if (TaskHandle != NULL) {
BaseType_t taskWoke = pdFALSE;
xTaskNotifyFromISR(TaskHandle, 0x01, eNotifyAction::eSetBits,
&taskWoke);
portYIELD_FROM_ISR(taskWoke);
}
}

View File

@@ -0,0 +1,57 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PDB_INT_N_OLD_H
#define PDB_INT_N_OLD_H
#include <pd.h>
class InterruptHandler {
public:
//Creates the thread to handle the Interrupt pin
static void init();
static void irqCallback();
private:
static void Thread(const void *arg);
static osThreadId TaskHandle;
static const size_t TaskStackSize = 1536 / 3;
static uint32_t TaskBuffer[TaskStackSize];
static osStaticThreadDef_t TaskControlBlock;
/*
* Hard Reset machine states
*/
enum hardrst_state {
PRLHRResetLayer,
PRLHRIndicateHardReset,
PRLHRRequestHardReset,
PRLHRWaitPHY,
PRLHRHardResetRequested,
PRLHRWaitPE,
PRLHRComplete
};
static enum hardrst_state hardrst_reset_layer();
static enum hardrst_state hardrst_indicate_hard_reset();
static enum hardrst_state hardrst_request_hard_reset();
static enum hardrst_state hardrst_wait_phy();
static enum hardrst_state hardrst_hard_reset_requested();
static enum hardrst_state hardrst_wait_pe();
static enum hardrst_state hardrst_complete();
};
#endif /* PDB_INT_N_OLD_H */

View File

@@ -0,0 +1,400 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PDB_PD_H
#define PDB_PD_H
#include <stdint.h>
#include "FreeRTOS.h"
#include "pdb_msg.h"
#include "cmsis_os.h"
#include "pdb_conf.h"
/*
* Macros for working with USB Power Delivery messages.
*
* This file is mostly written from the PD Rev. 2.0 spec, but the header is
* written from the Rev. 3.0 spec.
*/
/*
* PD Header
*/
#define PD_HDR_MSGTYPE_SHIFT 0
#define PD_HDR_MSGTYPE (0x1F << PD_HDR_MSGTYPE_SHIFT)
#define PD_HDR_DATAROLE_SHIFT 5
#define PD_HDR_DATAROLE (0x1 << PD_HDR_DATAROLE_SHIFT)
#define PD_HDR_SPECREV_SHIFT 6
#define PD_HDR_SPECREV (0x3 << PD_HDR_SPECREV_SHIFT)
#define PD_HDR_POWERROLE_SHIFT 8
#define PD_HDR_POWERROLE (1 << PD_HDR_POWERROLE_SHIFT)
#define PD_HDR_MESSAGEID_SHIFT 9
#define PD_HDR_MESSAGEID (0x7 << PD_HDR_MESSAGEID_SHIFT)
#define PD_HDR_NUMOBJ_SHIFT 12
#define PD_HDR_NUMOBJ (0x7 << PD_HDR_NUMOBJ_SHIFT)
#define PD_HDR_EXT (1 << 15)
/* Message types */
#define PD_MSGTYPE_GET(msg) (((msg)->hdr & PD_HDR_MSGTYPE) >> PD_HDR_MSGTYPE_SHIFT)
/* Control Message */
#define PD_MSGTYPE_GOODCRC 0x01
#define PD_MSGTYPE_GOTOMIN 0x02
#define PD_MSGTYPE_ACCEPT 0x03
#define PD_MSGTYPE_REJECT 0x04
#define PD_MSGTYPE_PING 0x05
#define PD_MSGTYPE_PS_RDY 0x06
#define PD_MSGTYPE_GET_SOURCE_CAP 0x07
#define PD_MSGTYPE_GET_SINK_CAP 0x08
#define PD_MSGTYPE_DR_SWAP 0x09
#define PD_MSGTYPE_PR_SWAP 0x0A
#define PD_MSGTYPE_VCONN_SWAP 0x0B
#define PD_MSGTYPE_WAIT 0x0C
#define PD_MSGTYPE_SOFT_RESET 0x0D
#define PD_MSGTYPE_NOT_SUPPORTED 0x10
#define PD_MSGTYPE_GET_SOURCE_CAP_EXTENDED 0x11
#define PD_MSGTYPE_GET_STATUS 0x12
#define PD_MSGTYPE_FR_SWAP 0x13
#define PD_MSGTYPE_GET_PPS_STATUS 0x14
#define PD_MSGTYPE_GET_COUNTRY_CODES 0x15
/* Data Message */
#define PD_MSGTYPE_SOURCE_CAPABILITIES 0x01
#define PD_MSGTYPE_REQUEST 0x02
#define PD_MSGTYPE_BIST 0x03
#define PD_MSGTYPE_SINK_CAPABILITIES 0x04
#define PD_MSGTYPE_BATTERY_STATUS 0x05
#define PD_MSGTYPE_ALERT 0x06
#define PD_MSGTYPE_GET_COUNTRY_INFO 0x07
#define PD_MSGTYPE_VENDOR_DEFINED 0x0F
/* Extended Message */
#define PD_MSGTYPE_SOURCE_CAPABILITIES_EXTENDED 0x01
#define PD_MSGTYPE_STATUS 0x02
#define PD_MSGTYPE_GET_BATTERY_CAP 0x03
#define PD_MSGTYPE_GET_BATTERY_STATUS 0x04
#define PD_MSGTYPE_BATTERY_CAPABILITIES 0x05
#define PD_MSGTYPE_GET_MANUFACTURER_INFO 0x06
#define PD_MSGTYPE_MANUFACTURER_INFO 0x07
#define PD_MSGTYPE_SECURITY_REQUEST 0x08
#define PD_MSGTYPE_SECURITY_RESPONSE 0x09
#define PD_MSGTYPE_FIRMWARE_UPDATE_REQUEST 0x0A
#define PD_MSGTYPE_FIRMWARE_UPDATE_RESPONSE 0x0B
#define PD_MSGTYPE_PPS_STATUS 0x0C
#define PD_MSGTYPE_COUNTRY_INFO 0x0D
#define PD_MSGTYPE_COUNTRY_CODES 0x0E
/* Data roles */
#define PD_DATAROLE_UFP (0x0 << PD_HDR_DATAROLE_SHIFT)
#define PD_DATAROLE_DFP (0x1 << PD_HDR_DATAROLE_SHIFT)
/* Specification revisions */
#define PD_SPECREV_1_0 (0x0 << PD_HDR_SPECREV_SHIFT)
#define PD_SPECREV_2_0 (0x1 << PD_HDR_SPECREV_SHIFT)
#define PD_SPECREV_3_0 (0x2 << PD_HDR_SPECREV_SHIFT)
/* Port power roles */
#define PD_POWERROLE_SINK (0x0 << PD_HDR_POWERROLE_SHIFT)
#define PD_POWERROLE_SOURCE (0x1 << PD_HDR_POWERROLE_SHIFT)
/* Message ID */
#define PD_MESSAGEID_GET(msg) (((msg)->hdr & PD_HDR_MESSAGEID) >> PD_HDR_MESSAGEID_SHIFT)
/* Number of data objects */
#define PD_NUMOBJ(n) (((n) << PD_HDR_NUMOBJ_SHIFT) & PD_HDR_NUMOBJ)
#define PD_NUMOBJ_GET(msg) (((msg)->hdr & PD_HDR_NUMOBJ) >> PD_HDR_NUMOBJ_SHIFT)
/*
* PD Extended Message Header
*/
#define PD_EXTHDR_DATA_SIZE_SHIFT 0
#define PD_EXTHDR_DATA_SIZE (0x1FF << PD_EXTHDR_DATA_SIZE_SHIFT)
#define PD_EXTHDR_REQUEST_CHUNK_SHIFT 10
#define PD_EXTHDR_REQUEST_CHUNK (1 << PD_EXTHDR_REQUEST_CHUNK_SHIFT)
#define PD_EXTHDR_CHUNK_NUMBER_SHIFT 11
#define PD_EXTHDR_CHUNK_NUMBER (0xF << PD_EXTHDR_CHUNK_NUMBER_SHIFT)
#define PD_EXTHDR_CHUNKED_SHIFT 15
#define PD_EXTHDR_CHUNKED (1 << PD_EXTHDR_CHUNKED_SHIFT)
/* Data size */
#define PD_DATA_SIZE(n) (((n) << PD_EXTHDR_DATA_SIZE_SHIFT) & PD_EXTHDR_DATA_SIZE)
#define PD_DATA_SIZE_GET(msg) (((msg)->exthdr & PD_EXTHDR_DATA_SIZE) >> PD_EXTHDR_DATA_SIZE_SHIFT)
/* Chunk number */
#define PD_CHUNK_NUMBER(n) (((n) << PD_EXTHDR_CHUNK_NUMBER_SHIFT) & PD_EXTHDR_CHUNK_NUMBER)
#define PD_CHUNK_NUMBER_GET(msg) (((msg)->exthdr & PD_EXTHDR_CHUNK_NUMBER) >> PD_EXTHDR_CHUNK_NUMBER_SHIFT)
/*
* PD Power Data Object
*/
#define PD_PDO_TYPE_SHIFT 30
#define PD_PDO_TYPE (0x3 << PD_PDO_TYPE_SHIFT)
/* PDO types */
#define PD_PDO_TYPE_FIXED ((unsigned) (0x0 << PD_PDO_TYPE_SHIFT))
#define PD_PDO_TYPE_BATTERY ((unsigned) (0x1 << PD_PDO_TYPE_SHIFT))
#define PD_PDO_TYPE_VARIABLE ((unsigned) (0x2 << PD_PDO_TYPE_SHIFT))
#define PD_PDO_TYPE_AUGMENTED ((unsigned) (0x3 << PD_PDO_TYPE_SHIFT))
#define PD_APDO_TYPE_SHIFT 28
#define PD_APDO_TYPE (0x3 << PD_APDO_TYPE_SHIFT)
/* APDO types */
#define PD_APDO_TYPE_PPS (0x0 << PD_APDO_TYPE_SHIFT)
/* PD Source Fixed PDO */
#define PD_PDO_SRC_FIXED_DUAL_ROLE_PWR_SHIFT 29
#define PD_PDO_SRC_FIXED_DUAL_ROLE_PWR (1 << PD_PDO_SRC_FIXED_DUAL_ROLE_PWR_SHIFT)
#define PD_PDO_SRC_FIXED_USB_SUSPEND_SHIFT 28
#define PD_PDO_SRC_FIXED_USB_SUSPEND (1 << PD_PDO_SRC_FIXED_USB_SUSPEND_SHIFT)
#define PD_PDO_SRC_FIXED_UNCONSTRAINED_SHIFT 27
#define PD_PDO_SRC_FIXED_UNCONSTRAINED (1 << PD_PDO_SRC_FIXED_UNCONSTRAINED_SHIFT)
#define PD_PDO_SRC_FIXED_USB_COMMS_SHIFT 26
#define PD_PDO_SRC_FIXED_USB_COMMS (1 << PD_PDO_SRC_FIXED_USB_COMMS_SHIFT)
#define PD_PDO_SRC_FIXED_DUAL_ROLE_DATA_SHIFT 25
#define PD_PDO_SRC_FIXED_DUAL_ROLE_DATA (1 << PD_PDO_SRC_FIXED_DUAL_ROLE_DATA_SHIFT)
#define PD_PDO_SRC_FIXED_UNCHUNKED_EXT_MSG_SHIFT 24
#define PD_PDO_SRC_FIXED_UNCHUNKED_EXT_MSG (1 << PD_PDO_SRC_FIXED_UNCHUNKED_EXT_MSG_SHIFT)
#define PD_PDO_SRC_FIXED_PEAK_CURRENT_SHIFT 20
#define PD_PDO_SRC_FIXED_PEAK_CURRENT (0x3 << PD_PDO_SRC_FIXED_PEAK_CURRENT_SHIFT)
#define PD_PDO_SRC_FIXED_VOLTAGE_SHIFT 10
#define PD_PDO_SRC_FIXED_VOLTAGE (0x3FF << PD_PDO_SRC_FIXED_VOLTAGE_SHIFT)
#define PD_PDO_SRC_FIXED_CURRENT_SHIFT 0
#define PD_PDO_SRC_FIXED_CURRENT (0x3FF << PD_PDO_SRC_FIXED_CURRENT_SHIFT)
/* PD Source Fixed PDO current */
#define PD_PDO_SRC_FIXED_CURRENT_GET(pdo) (((pdo) & PD_PDO_SRC_FIXED_CURRENT) >> PD_PDO_SRC_FIXED_CURRENT_SHIFT)
/* PD Source Fixed PDO voltage */
#define PD_PDO_SRC_FIXED_VOLTAGE_GET(pdo) (((pdo) & PD_PDO_SRC_FIXED_VOLTAGE) >> PD_PDO_SRC_FIXED_VOLTAGE_SHIFT)
/* PD Programmable Power Supply APDO */
#define PD_APDO_PPS_MAX_VOLTAGE_SHIFT 17
#define PD_APDO_PPS_MAX_VOLTAGE (0xFF << PD_APDO_PPS_MAX_VOLTAGE_SHIFT)
#define PD_APDO_PPS_MIN_VOLTAGE_SHIFT 8
#define PD_APDO_PPS_MIN_VOLTAGE (0xFF << PD_APDO_PPS_MIN_VOLTAGE_SHIFT)
#define PD_APDO_PPS_CURRENT_SHIFT 0
#define PD_APDO_PPS_CURRENT (0x7F << PD_APDO_PPS_CURRENT_SHIFT)
/* PD Programmable Power Supply APDO voltages */
#define PD_APDO_PPS_MAX_VOLTAGE_GET(pdo) (((pdo) & PD_APDO_PPS_MAX_VOLTAGE) >> PD_APDO_PPS_MAX_VOLTAGE_SHIFT)
#define PD_APDO_PPS_MIN_VOLTAGE_GET(pdo) (((pdo) & PD_APDO_PPS_MIN_VOLTAGE) >> PD_APDO_PPS_MIN_VOLTAGE_SHIFT)
#define PD_APDO_PPS_MAX_VOLTAGE_SET(v) (((v) << PD_APDO_PPS_MAX_VOLTAGE_SHIFT) & PD_APDO_PPS_MAX_VOLTAGE)
#define PD_APDO_PPS_MIN_VOLTAGE_SET(v) (((v) << PD_APDO_PPS_MIN_VOLTAGE_SHIFT) & PD_APDO_PPS_MIN_VOLTAGE)
/* PD Programmable Power Supply APDO current */
#define PD_APDO_PPS_CURRENT_GET(pdo) ((uint8_t) (((pdo) & PD_APDO_PPS_CURRENT) >> PD_APDO_PPS_CURRENT_SHIFT))
#define PD_APDO_PPS_CURRENT_SET(i) (((i) << PD_APDO_PPS_CURRENT_SHIFT) & PD_APDO_PPS_CURRENT)
/* PD Sink Fixed PDO */
#define PD_PDO_SNK_FIXED_DUAL_ROLE_PWR_SHIFT 29
#define PD_PDO_SNK_FIXED_DUAL_ROLE_PWR (1 << PD_PDO_SNK_FIXED_DUAL_ROLE_PWR_SHIFT)
#define PD_PDO_SNK_FIXED_HIGHER_CAP_SHIFT 28
#define PD_PDO_SNK_FIXED_HIGHER_CAP (1 << PD_PDO_SNK_FIXED_HIGHER_CAP_SHIFT)
#define PD_PDO_SNK_FIXED_UNCONSTRAINED_SHIFT 27
#define PD_PDO_SNK_FIXED_UNCONSTRAINED (1 << PD_PDO_SNK_FIXED_UNCONSTRAINED_SHIFT)
#define PD_PDO_SNK_FIXED_USB_COMMS_SHIFT 26
#define PD_PDO_SNK_FIXED_USB_COMMS (1 << PD_PDO_SNK_FIXED_USB_COMMS_SHIFT)
#define PD_PDO_SNK_FIXED_DUAL_ROLE_DATA_SHIFT 25
#define PD_PDO_SNK_FIXED_DUAL_ROLE_DATA (1 << PD_PDO_SNK_FIXED_DUAL_ROLE_DATA_SHIFT)
#define PD_PDO_SNK_FIXED_VOLTAGE_SHIFT 10
#define PD_PDO_SNK_FIXED_VOLTAGE (0x3FF << PD_PDO_SNK_FIXED_VOLTAGE_SHIFT)
#define PD_PDO_SNK_FIXED_CURRENT_SHIFT 0
#define PD_PDO_SNK_FIXED_CURRENT (0x3FF << PD_PDO_SNK_FIXED_CURRENT_SHIFT)
/* PD Sink Fixed PDO current */
#define PD_PDO_SNK_FIXED_CURRENT_SET(i) (((i) << PD_PDO_SNK_FIXED_CURRENT_SHIFT) & PD_PDO_SNK_FIXED_CURRENT)
/* PD Sink Fixed PDO voltage */
#define PD_PDO_SNK_FIXED_VOLTAGE_SET(v) (((v) << PD_PDO_SNK_FIXED_VOLTAGE_SHIFT) & PD_PDO_SNK_FIXED_VOLTAGE)
/*
* PD Request Data Object
*/
#define PD_RDO_OBJPOS_SHIFT 28
#define PD_RDO_OBJPOS (0x7 << PD_RDO_OBJPOS_SHIFT)
#define PD_RDO_GIVEBACK_SHIFT 27
#define PD_RDO_GIVEBACK (1 << PD_RDO_GIVEBACK_SHIFT)
#define PD_RDO_CAP_MISMATCH_SHIFT 26
#define PD_RDO_CAP_MISMATCH (1 << PD_RDO_CAP_MISMATCH_SHIFT)
#define PD_RDO_USB_COMMS_SHIFT 25
#define PD_RDO_USB_COMMS (1 << PD_RDO_USB_COMMS_SHIFT)
#define PD_RDO_NO_USB_SUSPEND_SHIFT 24
#define PD_RDO_NO_USB_SUSPEND (1 << PD_RDO_NO_USB_SUSPEND_SHIFT)
#define PD_RDO_UNCHUNKED_EXT_MSG_SHIFT 23
#define PD_RDO_UNCHUNKED_EXT_MSG (1 << PD_RDO_UNCHUNKED_EXT_MSG_SHIFT)
#define PD_RDO_OBJPOS_SET(i) (((i) << PD_RDO_OBJPOS_SHIFT) & PD_RDO_OBJPOS)
#define PD_RDO_OBJPOS_GET(msg) (((msg)->obj[0] & PD_RDO_OBJPOS) >> PD_RDO_OBJPOS_SHIFT)
/* Fixed and Variable RDO, no GiveBack support */
#define PD_RDO_FV_CURRENT_SHIFT 10
#define PD_RDO_FV_CURRENT (0x3FF << PD_RDO_FV_CURRENT_SHIFT)
#define PD_RDO_FV_MAX_CURRENT_SHIFT 0
#define PD_RDO_FV_MAX_CURRENT (0x3FF << PD_RDO_FV_MAX_CURRENT_SHIFT)
#define PD_RDO_FV_CURRENT_SET(i) (((i) << PD_RDO_FV_CURRENT_SHIFT) & PD_RDO_FV_CURRENT)
#define PD_RDO_FV_MAX_CURRENT_SET(i) (((i) << PD_RDO_FV_MAX_CURRENT_SHIFT) & PD_RDO_FV_MAX_CURRENT)
/* Fixed and Variable RDO with GiveBack support */
#define PD_RDO_FV_MIN_CURRENT_SHIFT 0
#define PD_RDO_FV_MIN_CURRENT (0x3FF << PD_RDO_FV_MIN_CURRENT_SHIFT)
#define PD_RDO_FV_MIN_CURRENT_SET(i) (((i) << PD_RDO_FV_MIN_CURRENT_SHIFT) & PD_RDO_FV_MIN_CURRENT)
/* TODO: Battery RDOs */
/* Programmable RDO */
#define PD_RDO_PROG_VOLTAGE_SHIFT 9
#define PD_RDO_PROG_VOLTAGE (0x7FF << PD_RDO_PROG_VOLTAGE_SHIFT)
#define PD_RDO_PROG_CURRENT_SHIFT 0
#define PD_RDO_PROG_CURRENT (0x7F << PD_RDO_PROG_CURRENT_SHIFT)
#define PD_RDO_PROG_VOLTAGE_SET(i) (((i) << PD_RDO_PROG_VOLTAGE_SHIFT) & PD_RDO_PROG_VOLTAGE)
#define PD_RDO_PROG_CURRENT_SET(i) (((i) << PD_RDO_PROG_CURRENT_SHIFT) & PD_RDO_PROG_CURRENT)
/*
* Time values
*
* Where a range is specified, the middle of the range (rounded down to the
* nearest millisecond) is used.
*/
#define PD_T_CHUNKING_NOT_SUPPORTED (450)
#define PD_T_HARD_RESET_COMPLETE (1000)
#define PD_T_PS_TRANSITION (5000)
#define PD_T_SENDER_RESPONSE (2700)
#define PD_T_SINK_REQUEST (1000)
#define PD_T_TYPEC_SINK_WAIT_CAP (1000)
#define PD_T_PD_DEBOUNCE (2000)
/*
* Counter maximums
*/
#define PD_N_HARD_RESET_COUNT 2
/*
* Value parameters
*/
#define PD_MAX_EXT_MSG_LEN 260
#define PD_MAX_EXT_MSG_CHUNK_LEN 26
#define PD_MAX_EXT_MSG_LEGACY_LEN 26
/*
* Unit conversions
*
* V: volt
* CV: centivolt
* MV: millivolt
* PRV: Programmable RDO voltage unit (20 mV)
* PDV: Power Delivery voltage unit (50 mV)
* PAV: PPS APDO voltage unit (100 mV)
*
* A: ampere
* CA: centiampere
* MA: milliampere
* PDI: Power Delivery current unit (10 mA)
* PAI: PPS APDO current unit (50 mA)
*
* W: watt
* CW: centiwatt
* MW: milliwatt
*
* O: ohm
* CO: centiohm
* MO: milliohm
*/
#define PD_MV2PRV(mv) ((mv) / 20)
#define PD_MV2PDV(mv) ((mv) / 50)
#define PD_MV2PAV(mv) ((mv) / 100)
#define PD_PRV2MV(prv) ((prv) * 20)
#define PD_PDV2MV(pdv) ((pdv) * 50)
#define PD_PAV2MV(pav) ((pav) * 100)
#define PD_MA2CA(ma) (((ma) + 10 - 1) / 10)
#define PD_MA2PDI(ma) (((ma) + 10 - 1) / 10)
#define PD_MA2PAI(ma) (((ma) + 50 - 1) / 50)
#define PD_CA2PAI(ca) (((ca) + 5 - 1) / 5)
#define PD_PDI2MA(pdi) ((pdi) * 10)
#define PD_PAI2MA(pai) ((pai) * 50)
#define PD_PAI2CA(pai) ((pai) * 5)
#define PD_MW2CW(mw) ((mw) / 10)
#define PD_MO2CO(mo) ((mo) / 10)
/* Get portions of a voltage in more normal units */
#define PD_MV_V(mv) ((mv) / 1000)
#define PD_MV_MV(mv) ((mv) % 1000)
#define PD_PDV_V(pdv) ((pdv) / 20)
#define PD_PDV_CV(pdv) (5 * ((pdv) % 20))
#define PD_PAV_V(pav) ((pav) / 10)
#define PD_PAV_CV(pav) (10 * ((pav) % 10))
/* Get portions of a PD current in more normal units */
#define PD_PDI_A(pdi) ((pdi) / 100)
#define PD_PDI_CA(pdi) ((pdi) % 100)
#define PD_PAI_A(pai) ((pai) / 20)
#define PD_PAI_CA(pai) (5 * ((pai) % 20))
/* Get portions of a power in more normal units */
#define PD_CW_W(cw) ((cw) / 100)
#define PD_CW_CW(cw) ((cw) % 100)
/* Get portions of a resistance in more normal units */
#define PD_CO_O(co) ((co) / 100)
#define PD_CO_CO(co) ((co) % 100)
/*
* Unit constants
*/
#define PD_MV_MIN 0
#define PD_MV_MAX 21000
#define PD_PDV_MIN PD_MV2PDV(PD_MV_MIN)
#define PD_PDV_MAX PD_MV2PDV(PD_MV_MAX)
#define PD_MA_MIN 0
#define PD_MA_MAX 5000
#define PD_CA_MIN PD_MA2CA(PD_MA_MIN)
#define PD_CA_MAX PD_MA2CA(PD_MA_MAX)
#define PD_PDI_MIN PD_MA2PDI(PD_MA_MIN)
#define PD_PDI_MAX PD_MA2PDI(PD_MA_MAX)
#define PD_MW_MIN 0
#define PD_MW_MAX 100000
#define PD_MO_MIN 500
#define PD_MO_MAX 655350
/*
* FUSB Type-C Current level enum
*/
enum fusb_typec_current {
fusb_tcc_none = 0,
fusb_tcc_default = 1,
fusb_tcc_1_5 = 2,
fusb_sink_tx_ng = 2,
fusb_tcc_3_0 = 3,
fusb_sink_tx_ok = 3
};
#endif /* PDB_PD_H */

View File

@@ -0,0 +1,32 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PDB_CONF_H
#define PDB_CONF_H
/* Number of messages in the message pool */
#define PDB_MSG_POOL_SIZE 4
#define EVENT_MASK(x) (1<<x)
#define eventmask_t uint32_t
/* PD Buddy thread priorities */
#define PDB_PRIO_PE (osPriorityNormal)
#define PDB_PRIO_PRL (osPriorityBelowNormal)
#define PDB_PRIO_PRL_INT_N (osPriorityLow)
#endif /* PDB_CONF_H */

View File

@@ -0,0 +1,55 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PDB_MSG_H
#define PDB_MSG_H
#include <stdint.h>
/*
* PD message union
*
* This can be safely read from or written to in any form without any
* transformations because everything in the system is little-endian.
*
* Two bytes of padding are required at the start to prevent problems due to
* alignment. Specifically, without the padding, &obj[0] != &bytes[2], making
* the statement in the previous paragraph invalid.
*/
union pd_msg {
struct {
uint8_t _pad1[2];
uint8_t bytes[30];
} __attribute__((packed));
struct {
uint8_t _pad2[2];
uint16_t hdr;
union {
uint32_t obj[7];
struct {
uint16_t exthdr;
uint8_t data[26];
};
};
} __attribute__((packed));
};
#endif /* PDB_MSG_H */

View File

@@ -0,0 +1,692 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "policy_engine.h"
#include <stdbool.h>
#include "int_n.h"
#include <pd.h>
#include "protocol_tx.h"
#include "fusb302b.h"
bool PolicyEngine::pdNegotiationComplete;
int PolicyEngine::current_voltage_mv;
int PolicyEngine::_requested_voltage;
bool PolicyEngine::_unconstrained_power;
union pd_msg PolicyEngine::currentMessage;
uint16_t PolicyEngine::hdr_template;
bool PolicyEngine::_explicit_contract;
int8_t PolicyEngine::_hard_reset_counter;
int8_t PolicyEngine::_old_tcc_match;
uint8_t PolicyEngine::_pps_index;
uint8_t PolicyEngine::_last_pps;
osThreadId PolicyEngine::TaskHandle = NULL;
uint32_t PolicyEngine::TaskBuffer[PolicyEngine::TaskStackSize];
osStaticThreadDef_t PolicyEngine::TaskControlBlock;
union pd_msg PolicyEngine::tempMessage;
union pd_msg PolicyEngine::_last_dpm_request;
PolicyEngine::policy_engine_state PolicyEngine::state = PESinkStartup;
StaticQueue_t PolicyEngine::xStaticQueue;
uint8_t PolicyEngine::ucQueueStorageArea[PDB_MSG_POOL_SIZE
* sizeof(union pd_msg)];
QueueHandle_t PolicyEngine::messagesWaiting = NULL;
EventGroupHandle_t PolicyEngine::xEventGroupHandle = NULL;
StaticEventGroup_t PolicyEngine::xCreatedEventGroup;
void PolicyEngine::init() {
messagesWaiting = xQueueCreateStatic(PDB_MSG_POOL_SIZE,
sizeof(union pd_msg), ucQueueStorageArea, &xStaticQueue);
//Create static thread at PDB_PRIO_PE priority
osThreadStaticDef(PolEng, pe_task, PDB_PRIO_PE, 0, TaskStackSize,
TaskBuffer, &TaskControlBlock);
TaskHandle = osThreadCreate(osThread(PolEng), NULL);
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
}
void PolicyEngine::notify(uint32_t notification) {
if (xEventGroupHandle != NULL) {
xEventGroupSetBits(xEventGroupHandle, notification);
}
}
void PolicyEngine::pe_task(const void *arg) {
(void) arg;
//Internal thread loop
hdr_template = PD_DATAROLE_UFP | PD_POWERROLE_SINK;
/* Initialize the old_tcc_match */
_old_tcc_match = -1;
/* Initialize the pps_index */
_pps_index = 8;
/* Initialize the last_pps */
_last_pps = 8;
for (;;) {
//Loop based on state
switch (state) {
case PESinkStartup:
state = pe_sink_startup();
break;
case PESinkDiscovery:
state = pe_sink_discovery();
break;
case PESinkWaitCap:
state = pe_sink_wait_cap();
break;
case PESinkEvalCap:
state = pe_sink_eval_cap();
break;
case PESinkSelectCap:
state = pe_sink_select_cap();
break;
case PESinkTransitionSink:
state = pe_sink_transition_sink();
break;
case PESinkReady:
state = pe_sink_ready();
break;
case PESinkGetSourceCap:
state = pe_sink_get_source_cap();
break;
case PESinkGiveSinkCap:
state = pe_sink_give_sink_cap();
break;
case PESinkHardReset:
state = pe_sink_hard_reset();
break;
case PESinkTransitionDefault:
state = pe_sink_transition_default();
break;
case PESinkSoftReset:
state = pe_sink_soft_reset();
break;
case PESinkSendSoftReset:
state = pe_sink_send_soft_reset();
break;
case PESinkSendNotSupported:
state = pe_sink_send_not_supported();
break;
case PESinkChunkReceived:
state = pe_sink_chunk_received();
break;
case PESinkSourceUnresponsive:
state = pe_sink_source_unresponsive();
break;
case PESinkNotSupportedReceived:
state = pe_sink_not_supported_received();
break;
default:
state = PESinkStartup;
break;
}
}
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_startup() {
/* We don't have an explicit contract currently */
_explicit_contract = false;
//If desired could send an alert that PD is starting
/* No need to reset the protocol layer here. There are two ways into this
* state: startup and exiting hard reset. On startup, the protocol layer
* is reset by the startup procedure. When exiting hard reset, the
* protocol layer is reset by the hard reset state machine. Since it's
* already done somewhere else, there's no need to do it again here. */
return PESinkDiscovery;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_discovery() {
/* Wait for VBUS. Since it's our only power source, we already know that
* we have it, so just move on. */
return PESinkWaitCap;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_wait_cap() {
/* Fetch a message from the protocol layer */
eventmask_t evt = 0;
if (readMessage()) {
evt = PDB_EVT_PE_MSG_RX_PEND;
} else {
evt = waitForEvent(
PDB_EVT_PE_MSG_RX | PDB_EVT_PE_I_OVRTEMP | PDB_EVT_PE_RESET,
//Wait for cap timeout
PD_T_TYPEC_SINK_WAIT_CAP);
}
/* If we timed out waiting for Source_Capabilities, send a hard reset */
if (evt == 0) {
return PESinkHardReset;
}
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkWaitCap;
}
/* If we're too hot, we shouldn't negotiate power yet */
if (evt & PDB_EVT_PE_I_OVRTEMP) {
return PESinkWaitCap;
}
/* If we got a message */
if (evt & (PDB_EVT_PE_MSG_RX | PDB_EVT_PE_MSG_RX_PEND)) {
/* Get the message */
while ((evt & PDB_EVT_PE_MSG_RX_PEND) || readMessage() == true) {
/* If we got a Source_Capabilities message, read it. */
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOURCE_CAPABILITIES
&& PD_NUMOBJ_GET(&tempMessage) > 0) {
/* First, determine what PD revision we're using */
if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_1_0) {
/* If the other end is using at least version 3.0, we'll
* use version 3.0. */
if ((tempMessage.hdr & PD_HDR_SPECREV) >= PD_SPECREV_3_0) {
hdr_template |= PD_SPECREV_3_0;
/* Otherwise, use 2.0. Don't worry about the 1.0 case
* because we don't have hardware for PD 1.0 signaling. */
} else {
hdr_template |= PD_SPECREV_2_0;
}
}
return PESinkEvalCap;
/* If the message was a Soft_Reset, do the soft reset procedure */
}
evt = 0;
}
return PESinkWaitCap; //wait for more messages?
}
/* If we failed to get a message, send a hard reset */
return PESinkHardReset;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_eval_cap() {
/* If we have a Source_Capabilities message, remember the index of the
* first PPS APDO so we can check if the request is for a PPS APDO in
* PE_SNK_Select_Cap. */
/* Start by assuming we won't find a PPS APDO (set the index greater
* than the maximum possible) */
_pps_index = 8;
/* Search for the first PPS APDO */
for (int8_t i = 0; i < PD_NUMOBJ_GET(&tempMessage); i++) {
if ((tempMessage.obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED
&& (tempMessage.obj[i] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS) {
_pps_index = i + 1;
break;
}
}
/* New capabilities also means we can't be making a request from the
* same PPS APDO */
_last_pps = 8;
/* Ask the DPM what to request */
if (pdbs_dpm_evaluate_capability(&tempMessage, &_last_dpm_request)) {
return PESinkSelectCap;
}
return PESinkWaitCap;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_select_cap() {
/* Transmit the request */
waitForEvent(0xFFFF, 0); //clear pending
ProtocolTransmit::pushMessage(&_last_dpm_request);
//Send indication that there is a message pending
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
eventmask_t evt = waitForEvent(
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET || evt == 0) {
return PESinkTransitionDefault;
}
/* If the message transmission failed, send a hard reset */
if ((evt & PDB_EVT_PE_TX_ERR) == PDB_EVT_PE_TX_ERR) {
return PESinkHardReset;
}
/* Wait for a response */
evt = waitForEvent(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET,
PD_T_SENDER_RESPONSE);
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkTransitionDefault;
}
/* If we didn't get a response before the timeout, send a hard reset */
if (evt == 0) {
return PESinkHardReset;
}
/* Get the response message */
if (messageWaiting()) {
readMessage();
/* If the source accepted our request, wait for the new power */
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_ACCEPT
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkTransitionSink;
/* If the message was a Soft_Reset, do the soft reset procedure */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkSoftReset;
/* If the message was Wait or Reject */
} else if ((PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_REJECT
|| PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_WAIT)
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
/* If we don't have an explicit contract, wait for capabilities */
if (!_explicit_contract) {
return PESinkWaitCap;
/* If we do have an explicit contract, go to the ready state */
} else {
return PESinkReady;
}
} else {
return PESinkSendSoftReset;
}
}
return PESinkHardReset;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_transition_sink() {
/* Wait for the PS_RDY message */
eventmask_t evt = waitForEvent(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET,
PD_T_PS_TRANSITION);
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkTransitionDefault;
}
/* If no message was received, send a hard reset */
if (evt == 0) {
return PESinkHardReset;
}
/* If we received a message, read it */
if (messageWaiting()) {
readMessage();
/* If we got a PS_RDY, handle it */
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_PS_RDY
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
/* We just finished negotiating an explicit contract */
_explicit_contract = true;
/* Set the output appropriately */
pdbs_dpm_transition_requested();
return PESinkReady;
/* If there was a protocol error, send a hard reset */
} else {
/* Turn off the power output before this hard reset to make sure we
* don't supply an incorrect voltage to the device we're powering.
*/
pdbs_dpm_transition_default();
return PESinkHardReset;
}
}
return PESinkHardReset;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_ready() {
eventmask_t evt;
/* Wait for an event */
evt = waitForEvent(
PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET | PDB_EVT_PE_I_OVRTEMP);
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkTransitionDefault;
}
/* If we overheated, send a hard reset */
if (evt & PDB_EVT_PE_I_OVRTEMP) {
return PESinkHardReset;
}
/* If we received a message */
if (evt & PDB_EVT_PE_MSG_RX) {
if (messageWaiting()) {
readMessage();
/* Ignore vendor-defined messages */
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_VENDOR_DEFINED
&& PD_NUMOBJ_GET(&tempMessage) > 0) {
return PESinkReady;
/* Ignore Ping messages */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_PING
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkReady;
/* DR_Swap messages are not supported */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_DR_SWAP
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkSendNotSupported;
/* Get_Source_Cap messages are not supported */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_GET_SOURCE_CAP
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkSendNotSupported;
/* PR_Swap messages are not supported */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_PR_SWAP
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkSendNotSupported;
/* VCONN_Swap messages are not supported */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_VCONN_SWAP
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkSendNotSupported;
/* Request messages are not supported */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_REQUEST
&& PD_NUMOBJ_GET(&tempMessage) > 0) {
return PESinkSendNotSupported;
/* Sink_Capabilities messages are not supported */
} else if (PD_MSGTYPE_GET(&tempMessage)
== PD_MSGTYPE_SINK_CAPABILITIES
&& PD_NUMOBJ_GET(&tempMessage) > 0) {
return PESinkSendNotSupported;
/* Handle GotoMin messages */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_GOTOMIN
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
/* GiveBack is not supported */
return PESinkSendNotSupported;
/* Evaluate new Source_Capabilities */
} else if (PD_MSGTYPE_GET(&tempMessage)
== PD_MSGTYPE_SOURCE_CAPABILITIES
&& PD_NUMOBJ_GET(&tempMessage) > 0) {
/* Don't free the message: we need to keep the
* Source_Capabilities message so we can evaluate it. */
return PESinkEvalCap;
/* Give sink capabilities when asked */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_GET_SINK_CAP
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkGiveSinkCap;
/* If the message was a Soft_Reset, do the soft reset procedure */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkSoftReset;
/* PD 3.0 messges */
} else if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) {
/* If the message is a multi-chunk extended message, let it
* time out. */
if ((tempMessage.hdr & PD_HDR_EXT)
&& (PD_DATA_SIZE_GET(&tempMessage)
> PD_MAX_EXT_MSG_LEGACY_LEN)) {
return PESinkChunkReceived;
/* Tell the DPM a message we sent got a response of
* Not_Supported. */
} else if (PD_MSGTYPE_GET(&tempMessage)
== PD_MSGTYPE_NOT_SUPPORTED
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkNotSupportedReceived;
/* If we got an unknown message, send a soft reset */
} else {
return PESinkSendSoftReset;
}
/* If we got an unknown message, send a soft reset ??? */
} else {
return PESinkSendSoftReset;
}
}
}
return PESinkReady;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_get_source_cap() {
/* Get a message object */
union pd_msg *get_source_cap = &tempMessage;
/* Make a Get_Source_Cap message */
get_source_cap->hdr = hdr_template | PD_MSGTYPE_GET_SOURCE_CAP
| PD_NUMOBJ(0);
/* Transmit the Get_Source_Cap */
ProtocolTransmit::pushMessage(get_source_cap);
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
eventmask_t evt = waitForEvent(
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
/* Free the sent message */
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkTransitionDefault;
}
/* If the message transmission failed, send a hard reset */
if ((evt & PDB_EVT_PE_TX_DONE) == 0) {
return PESinkHardReset;
}
return PESinkReady;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_give_sink_cap() {
/* Get a message object */
union pd_msg *snk_cap = &tempMessage;
/* Get our capabilities from the DPM */
pdbs_dpm_get_sink_capability(snk_cap);
/* Transmit our capabilities */
ProtocolTransmit::pushMessage(snk_cap);
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
eventmask_t evt = waitForEvent(
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
/* Free the Sink_Capabilities message */
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkTransitionDefault;
}
/* If the message transmission failed, send a hard reset */
if ((evt & PDB_EVT_PE_TX_DONE) == 0) {
return PESinkHardReset;
}
return PESinkReady;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_hard_reset() {
/* If we've already sent the maximum number of hard resets, assume the
* source is unresponsive. */
if (_hard_reset_counter > PD_N_HARD_RESET_COUNT) {
return PESinkSourceUnresponsive;
}
//So, we could send a hardreset here; however that will cause a power cycle on the PSU end.. Which will then reset this MCU
//So therefore we went get anywhere :)
/* Increment HardResetCounter */
_hard_reset_counter++;
return PESinkTransitionDefault;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_transition_default() {
_explicit_contract = false;
/* Tell the DPM to transition to default power */
pdbs_dpm_transition_default();
/* There is no local hardware to reset. */
/* Since we never change our data role from UFP, there is no reason to set
* it here. */
return PESinkStartup;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_soft_reset() {
/* No need to explicitly reset the protocol layer here. It resets itself
* when a Soft_Reset message is received. */
/* Get a message object */
union pd_msg accept;
/* Make an Accept message */
accept.hdr = hdr_template | PD_MSGTYPE_ACCEPT | PD_NUMOBJ(0);
/* Transmit the Accept */
ProtocolTransmit::pushMessage(&accept);
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
eventmask_t evt = waitForEvent(
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
/* Free the sent message */
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkTransitionDefault;
}
/* If the message transmission failed, send a hard reset */
if ((evt & PDB_EVT_PE_TX_DONE) == 0) {
return PESinkHardReset;
}
return PESinkWaitCap;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_send_soft_reset() {
/* No need to explicitly reset the protocol layer here. It resets itself
* just before a Soft_Reset message is transmitted. */
/* Get a message object */
union pd_msg *softrst = &tempMessage;
/* Make a Soft_Reset message */
softrst->hdr = hdr_template | PD_MSGTYPE_SOFT_RESET | PD_NUMOBJ(0);
/* Transmit the soft reset */
ProtocolTransmit::pushMessage(softrst);
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
eventmask_t evt = waitForEvent(
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkTransitionDefault;
}
/* If the message transmission failed, send a hard reset */
if ((evt & PDB_EVT_PE_TX_DONE) == 0) {
return PESinkHardReset;
}
/* Wait for a response */
evt = waitForEvent(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET,
PD_T_SENDER_RESPONSE);
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkTransitionDefault;
}
/* If we didn't get a response before the timeout, send a hard reset */
if (evt == 0) {
return PESinkHardReset;
}
/* Get the response message */
if (messageWaiting()) {
readMessage();
/* If the source accepted our soft reset, wait for capabilities. */
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_ACCEPT
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkWaitCap;
/* If the message was a Soft_Reset, do the soft reset procedure */
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
return PESinkSoftReset;
/* Otherwise, send a hard reset */
} else {
return PESinkHardReset;
}
}
return PESinkHardReset;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_send_not_supported() {
/* Get a message object */
union pd_msg *not_supported = &tempMessage;
if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_2_0) {
/* Make a Reject message */
not_supported->hdr = hdr_template | PD_MSGTYPE_REJECT | PD_NUMOBJ(0);
} else if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) {
/* Make a Not_Supported message */
not_supported->hdr = hdr_template | PD_MSGTYPE_NOT_SUPPORTED
| PD_NUMOBJ(0);
}
/* Transmit the message */
ProtocolTransmit::pushMessage(not_supported);
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
eventmask_t evt = waitForEvent(
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkTransitionDefault;
}
/* If the message transmission failed, send a soft reset */
if ((evt & PDB_EVT_PE_TX_DONE) == 0) {
return PESinkSendSoftReset;
}
return PESinkReady;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_chunk_received() {
/* Wait for tChunkingNotSupported */
eventmask_t evt = waitForEvent(PDB_EVT_PE_RESET,
PD_T_CHUNKING_NOT_SUPPORTED);
/* If we got reset signaling, transition to default */
if (evt & PDB_EVT_PE_RESET) {
return PESinkTransitionDefault;
}
return PESinkSendNotSupported;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_not_supported_received() {
/* Inform the Device Policy Manager that we received a Not_Supported
* message. */
return PESinkReady;
}
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_source_unresponsive() {
//Sit and chill, as PD is not working
osDelay(PD_T_PD_DEBOUNCE);
return PESinkSourceUnresponsive;
}
uint32_t PolicyEngine::waitForEvent(uint32_t mask, uint32_t ticksToWait) {
return xEventGroupWaitBits(xEventGroupHandle, mask, mask, pdFALSE,
ticksToWait);
}
bool PolicyEngine::isPD3_0() {
return (hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0;
}

View File

@@ -0,0 +1,198 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PDB_POLICY_ENGINE_H
#define PDB_POLICY_ENGINE_H
#include <pd.h>
/*
* Events for the Policy Engine thread, used internally + sent by user code
*
*/
#define PDB_EVT_PE_RESET EVENT_MASK(0)
#define PDB_EVT_PE_MSG_RX EVENT_MASK(1)
#define PDB_EVT_PE_TX_DONE EVENT_MASK(2)
#define PDB_EVT_PE_TX_ERR EVENT_MASK(3)
#define PDB_EVT_PE_HARD_SENT EVENT_MASK(4)
#define PDB_EVT_PE_I_OVRTEMP EVENT_MASK(5)
#define PDB_EVT_PE_MSG_RX_PEND EVENT_MASK(7) /* Never SEND THIS DIRECTLY*/
class PolicyEngine {
public:
//Sets up internal state and registers the thread
static void init();
//Push an incoming message to the Policy Engine
static void handleMessage(union pd_msg *msg);
//Send a notification
static void notify(uint32_t notification);
//Returns true if headers indicate PD3.0 compliant
static bool isPD3_0();
static bool setupCompleteOrTimedOut() {
if (pdNegotiationComplete)
return true;
if (state == policy_engine_state::PESinkSourceUnresponsive)
return true;
if (state == policy_engine_state::PESinkReady)
return true;
return false;
}
//Has pd negotiation completed
static bool pdHasNegotiated() {
return pdNegotiationComplete;
}
private:
static bool pdNegotiationComplete;
static int current_voltage_mv; //The current voltage PD is expecting
static int _requested_voltage; //The voltage the unit wanted to requests
static bool _unconstrained_power; // If the source is unconstrained
//Current message being handled
static union pd_msg currentMessage;
/* PD message header template */
static uint16_t hdr_template;
/* Whether or not we have an explicit contract */
static bool _explicit_contract;
/* The number of hard resets we've sent */
static int8_t _hard_reset_counter;
/* The result of the last Type-C Current match comparison */
static int8_t _old_tcc_match;
/* The index of the first PPS APDO */
static uint8_t _pps_index;
/* The index of the just-requested PPS APDO */
static uint8_t _last_pps;
static void pe_task(const void *arg);
enum policy_engine_state {
PESinkStartup,
PESinkDiscovery,
PESinkWaitCap,
PESinkEvalCap,
PESinkSelectCap,
PESinkTransitionSink,
PESinkReady,
PESinkGetSourceCap,
PESinkGiveSinkCap,
PESinkHardReset,
PESinkTransitionDefault,
PESinkSoftReset,
PESinkSendSoftReset,
PESinkSendNotSupported,
PESinkChunkReceived,
PESinkNotSupportedReceived,
PESinkSourceUnresponsive
};
static enum policy_engine_state pe_sink_startup();
static enum policy_engine_state pe_sink_discovery();
static enum policy_engine_state pe_sink_wait_cap();
static enum policy_engine_state pe_sink_eval_cap();
static enum policy_engine_state pe_sink_select_cap();
static enum policy_engine_state pe_sink_transition_sink();
static enum policy_engine_state pe_sink_ready();
static enum policy_engine_state pe_sink_get_source_cap();
static enum policy_engine_state pe_sink_give_sink_cap();
static enum policy_engine_state pe_sink_hard_reset();
static enum policy_engine_state pe_sink_transition_default();
static enum policy_engine_state pe_sink_soft_reset();
static enum policy_engine_state pe_sink_send_soft_reset();
static enum policy_engine_state pe_sink_send_not_supported();
static enum policy_engine_state pe_sink_chunk_received();
static enum policy_engine_state pe_sink_not_supported_received();
static enum policy_engine_state pe_sink_source_unresponsive();
static EventGroupHandle_t xEventGroupHandle;
static StaticEventGroup_t xCreatedEventGroup;
static uint32_t waitForEvent(uint32_t mask, uint32_t ticksToWait =
portMAX_DELAY);
//Task resources
static osThreadId TaskHandle;
static const size_t TaskStackSize = 2048 / 4;
static uint32_t TaskBuffer[TaskStackSize];
static osStaticThreadDef_t TaskControlBlock;
static union pd_msg tempMessage;
static union pd_msg _last_dpm_request;
static policy_engine_state state;
//queue of up to PDB_MSG_POOL_SIZE messages to send
static StaticQueue_t xStaticQueue;
/* The array to use as the queue's storage area. This must be at least
uxQueueLength * uxItemSize bytes. */
static uint8_t ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)];
static QueueHandle_t messagesWaiting;
static bool messageWaiting();
//Read a pending message into the temp message
static bool readMessage();
// These callbacks are called to implement the logic for the iron to select the desired voltage
/*
* Create a Request message based on the given Source_Capabilities message. If
* capabilities is NULL, the last non-null Source_Capabilities message passes
* is used. If none has been provided, the behavior is undefined.
*
* Returns true if sufficient power is available, false otherwise.
*/
static bool pdbs_dpm_evaluate_capability(const union pd_msg *capabilities,
union pd_msg *request);
/*
* Create a Sink_Capabilities message for our current capabilities.
*/
static void pdbs_dpm_get_sink_capability(union pd_msg *cap);
/*
* Return whether or not GiveBack support is enabled.
*/
static bool pdbs_dpm_giveback_enabled();
/*
* Evaluate whether or not the currently offered Type-C Current can fulfill our
* power needs.
*
* Returns true if sufficient power is available, false otherwise.
*/
static bool pdbs_dpm_evaluate_typec_current(enum fusb_typec_current tcc);
/*
* Indicate that power negotiations are starting.
*/
static void pdbs_dpm_pd_start();
/*
* Transition the sink to default power.
*/
static void pdbs_dpm_transition_default();
/*
* Transition to the requested minimum current.
*/
static void pdbs_dpm_transition_min();
/*
* Transition to Sink Standby if necessary.
*/
static void pdbs_dpm_transition_standby();
/*
* Transition to the requested power level
*/
static void pdbs_dpm_transition_requested();
/*
* Transition to the Type-C Current power level
*/
static void pdbs_dpm_transition_typec();
};
#endif /* PDB_POLICY_ENGINE_H */

View File

@@ -0,0 +1,227 @@
/*
* policy_engine_user.cpp
*
* Created on: 14 Jun 2020
* Author: Ralim
*/
#include "pd.h"
#include "policy_engine.h"
#include "BSP_PD.h"
/* The current draw when the output is disabled */
#define DPM_MIN_CURRENT PD_MA2PDI(50)
/*
* Find the index of the first PDO from capabilities in the voltage range,
* using the desired order.
*
* If there is no such PDO, returns -1 instead.
*/
static int8_t dpm_get_range_fixed_pdo_index(const union pd_msg *caps) {
/* Get the number of PDOs */
uint8_t numobj = PD_NUMOBJ_GET(caps);
/* Get ready to iterate over the PDOs */
int8_t i;
int8_t step;
i = numobj - 1;
step = -1;
uint16_t current = 100; // in centiamps
uint16_t voltagemin = 8000;
uint16_t voltagemax = 10000;
/* Look at the PDOs to see if one falls in our voltage range. */
while (0 <= i && i < numobj) {
/* If we have a fixed PDO, its V is within our range, and its I is at
* least our desired I */
uint16_t v = PD_PDO_SRC_FIXED_VOLTAGE_GET(caps->obj[i]);
if ((caps->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
if ( PD_PDO_SRC_FIXED_CURRENT_GET(caps->obj[i]) >= current) {
if (v >= PD_MV2PDV(voltagemin) && v <= PD_MV2PDV(voltagemax)) {
return i;
}
}
}
i += step;
}
return -1;
}
bool PolicyEngine::pdbs_dpm_evaluate_capability(
const union pd_msg *capabilities, union pd_msg *request) {
/* Get the number of PDOs */
uint8_t numobj = PD_NUMOBJ_GET(capabilities);
/* Get whether or not the power supply is constrained */
_unconstrained_power =
capabilities->obj[0] & PD_PDO_SRC_FIXED_UNCONSTRAINED;
/* Make sure we have configuration */
/* Look at the PDOs to see if one matches our desires */
//Look against USB_PD_Desired_Levels to select in order of preference
for (uint8_t desiredLevel = 0; desiredLevel < USB_PD_Desired_Levels_Len;
desiredLevel++) {
for (uint8_t i = 0; i < numobj; i++) {
/* If we have a fixed PDO, its V equals our desired V, and its I is
* at least our desired I */
if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
//This is a fixed PDO entry
int voltage = PD_PDV2MV(
PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities->obj[i]));
int current = PD_PDO_SRC_FIXED_CURRENT_GET(
capabilities->obj[i]);
uint16_t desiredVoltage = USB_PD_Desired_Levels[(desiredLevel
* 2) + 0];
uint16_t desiredminCurrent = USB_PD_Desired_Levels[(desiredLevel
* 2) + 1];
//As pd stores current in 10mA increments, divide by 10
desiredminCurrent /= 10;
if (voltage == desiredVoltage) {
if (current >= desiredminCurrent) {
/* We got what we wanted, so build a request for that */
request->hdr = hdr_template | PD_MSGTYPE_REQUEST
| PD_NUMOBJ(1);
/* GiveBack disabled */
request->obj[0] =
PD_RDO_FV_MAX_CURRENT_SET(
current) | PD_RDO_FV_CURRENT_SET(current)
| PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(i + 1);
//We support usb comms (ish)
request->obj[0] |= PD_RDO_USB_COMMS;
/* Update requested voltage */
_requested_voltage = voltage;
return true;
}
}
}
}
}
/* Nothing matched (or no configuration), so get 5 V at low current */
request->hdr = hdr_template | PD_MSGTYPE_REQUEST | PD_NUMOBJ(1);
request->obj[0] =
PD_RDO_FV_MAX_CURRENT_SET(
DPM_MIN_CURRENT) | PD_RDO_FV_CURRENT_SET(DPM_MIN_CURRENT) | PD_RDO_NO_USB_SUSPEND
| PD_RDO_OBJPOS_SET(1);
/* If the output is enabled and we got here, it must be a capability
* mismatch. */
if (pdNegotiationComplete) {
request->obj[0] |= PD_RDO_CAP_MISMATCH;
}
request->obj[0] |= PD_RDO_USB_COMMS;
/* Update requested voltage */
_requested_voltage = 5000;
return false;
}
void PolicyEngine::pdbs_dpm_get_sink_capability(union pd_msg *cap) {
/* Keep track of how many PDOs we've added */
int numobj = 0;
/* If we have no configuration or want something other than 5 V, add a PDO
* for vSafe5V */
/* Minimum current, 5 V, and higher capability. */
cap->obj[numobj++] =
PD_PDO_TYPE_FIXED
| PD_PDO_SNK_FIXED_VOLTAGE_SET(
PD_MV2PDV(5000)) | PD_PDO_SNK_FIXED_CURRENT_SET(DPM_MIN_CURRENT);
/* Get the current we want */
uint16_t current = USB_PD_Desired_Levels[1] / 10; // In centi-amps
uint16_t voltage = USB_PD_Desired_Levels[0]; // in mv
/* Add a PDO for the desired power. */
cap->obj[numobj++] = PD_PDO_TYPE_FIXED
| PD_PDO_SNK_FIXED_VOLTAGE_SET(
PD_MV2PDV(voltage)) | PD_PDO_SNK_FIXED_CURRENT_SET(current);
/* Get the PDO from the voltage range */
int8_t i = dpm_get_range_fixed_pdo_index(cap);
/* If it's vSafe5V, set our vSafe5V's current to what we want */
if (i == 0) {
cap->obj[0] &= ~PD_PDO_SNK_FIXED_CURRENT;
cap->obj[0] |= PD_PDO_SNK_FIXED_CURRENT_SET(current);
} else {
/* If we want more than 5 V, set the Higher Capability flag */
if (PD_MV2PDV(voltage) != PD_MV2PDV(5000)) {
cap->obj[0] |= PD_PDO_SNK_FIXED_HIGHER_CAP;
}
/* If the range PDO is a different voltage than the preferred
* voltage, add it to the array. */
if (i
> 0&& PD_PDO_SRC_FIXED_VOLTAGE_GET(cap->obj[i]) != PD_MV2PDV(voltage)) {
cap->obj[numobj++] =
PD_PDO_TYPE_FIXED
| PD_PDO_SNK_FIXED_VOLTAGE_SET(
PD_PDO_SRC_FIXED_VOLTAGE_GET(cap->obj[i])) | PD_PDO_SNK_FIXED_CURRENT_SET(
PD_PDO_SRC_FIXED_CURRENT_GET(cap->obj[i]));
}
/* If we have three PDOs at this point, make sure the last two are
* sorted by voltage. */
if (numobj == 3
&& (cap->obj[1] & PD_PDO_SNK_FIXED_VOLTAGE)
> (cap->obj[2] & PD_PDO_SNK_FIXED_VOLTAGE)) {
cap->obj[1] ^= cap->obj[2];
cap->obj[2] ^= cap->obj[1];
cap->obj[1] ^= cap->obj[2];
}
}
/* Set the unconstrained power flag. */
if (_unconstrained_power) {
cap->obj[0] |= PD_PDO_SNK_FIXED_UNCONSTRAINED;
}
/* Set the USB communications capable flag. */
cap->obj[0] |= PD_PDO_SNK_FIXED_USB_COMMS;
/* Set the Sink_Capabilities message header */
cap->hdr = hdr_template | PD_MSGTYPE_SINK_CAPABILITIES | PD_NUMOBJ(numobj);
}
bool PolicyEngine::pdbs_dpm_evaluate_typec_current(
enum fusb_typec_current tcc) {
(void) tcc;
//This is for evaluating 5V static current advertised by resistors
/* We don't control the voltage anymore; it will always be 5 V. */
current_voltage_mv = _requested_voltage = 5000;
//For the soldering iron we accept this as a fallback, but it sucks
pdNegotiationComplete = false;
return true;
}
void PolicyEngine::pdbs_dpm_transition_default() {
/* Cast the dpm_data to the right type */
/* Pretend we requested 5 V */
current_voltage_mv = 5000;
/* Turn the output off */
pdNegotiationComplete = false;
}
void PolicyEngine::pdbs_dpm_transition_requested() {
/* Cast the dpm_data to the right type */
pdNegotiationComplete = true;
}
void PolicyEngine::handleMessage(union pd_msg *msg) {
xQueueSend(messagesWaiting, msg, 100);
}
bool PolicyEngine::messageWaiting() {
return uxQueueMessagesWaiting(messagesWaiting) > 0;
}
bool PolicyEngine::readMessage() {
return xQueueReceive(messagesWaiting, &tempMessage, 0) == pdTRUE;
}
void PolicyEngine::pdbs_dpm_transition_typec() {
//This means PD failed, so we either have a dump 5V only type C or a QC charger
//For now; treat this as failed neg
pdNegotiationComplete = false;
}

View File

@@ -0,0 +1,189 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "protocol_rx.h"
#include <stdlib.h>
#include "string.h"
#include <pd.h>
#include "policy_engine.h"
#include "protocol_tx.h"
#include "fusb302b.h"
osThreadId ProtocolReceive::TaskHandle = NULL;
EventGroupHandle_t ProtocolReceive::xEventGroupHandle = NULL;
StaticEventGroup_t ProtocolReceive::xCreatedEventGroup;
uint32_t ProtocolReceive::TaskBuffer[ProtocolReceive::TaskStackSize];
osStaticThreadDef_t ProtocolReceive::TaskControlBlock;
union pd_msg ProtocolReceive::tempMessage;
uint8_t ProtocolReceive::_rx_messageid;
uint8_t ProtocolReceive::_tx_messageidcounter;
/*
* PRL_Rx_Wait_for_PHY_Message state
*/
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_wait_phy() {
/* Wait for an event */
_rx_messageid = 0;
eventmask_t evt = waitForEvent(
PDB_EVT_PRLRX_RESET | PDB_EVT_PRLRX_I_GCRCSENT | PDB_EVT_PRLRX_I_RXPEND);
/* If we got a reset event, reset */
if (evt & PDB_EVT_PRLRX_RESET) {
waitForEvent(PDB_EVT_PRLRX_RESET, 0);
return PRLRxWaitPHY;
}
/* If we got an I_GCRCSENT event, read the message and decide what to do */
if (evt & PDB_EVT_PRLRX_I_GCRCSENT) {
/* Get a buffer to read the message into. Guaranteed to not fail
* because we have a big enough pool and are careful. */
union pd_msg *_rx_message = &tempMessage;
memset(&tempMessage, 0, sizeof(tempMessage));
/* Read the message */
fusb_read_message(_rx_message);
/* If it's a Soft_Reset, go to the soft reset state */
if (PD_MSGTYPE_GET(_rx_message) == PD_MSGTYPE_SOFT_RESET
&& PD_NUMOBJ_GET(_rx_message) == 0) {
return PRLRxReset;
} else {
/* Otherwise, check the message ID */
return PRLRxCheckMessageID;
}
} else if (evt & PDB_EVT_PRLRX_I_RXPEND) {
//There is an RX message pending that is not a Good CRC
union pd_msg *_rx_message = &tempMessage;
/* Read the message */
fusb_read_message(_rx_message);
return PRLRxWaitPHY;
}
return PRLRxWaitPHY;
}
/*
* PRL_Rx_Layer_Reset_for_Receive state
*/
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_reset() {
/* Reset MessageIDCounter */
_tx_messageidcounter = 0;
/* Clear stored MessageID */
_rx_messageid = -1;
/* TX transitions to its reset state */
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_RESET);
taskYIELD();
/* If we got a RESET signal, reset the machine */
if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) != 0) {
return PRLRxWaitPHY;
}
/* Go to the Check_MessageID state */
return PRLRxCheckMessageID;
}
volatile uint32_t rxCounter = 0;
/*
* PRL_Rx_Check_MessageID state
*/
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_check_messageid() {
/* If we got a RESET signal, reset the machine */
// if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) == PDB_EVT_PRLRX_RESET) {
// return PRLRxWaitPHY;
// }
/* If the message has the stored ID, we've seen this message before. Free
* it and don't pass it to the policy engine. */
/* Otherwise, there's either no stored ID or this message has an ID we
* haven't just seen. Transition to the Store_MessageID state. */
// if (PD_MESSAGEID_GET(&tempMessage) == _rx_messageid) {
// return PRLRxWaitPHY;
// } else
{
rxCounter++;
return PRLRxStoreMessageID;
}
}
/*
* PRL_Rx_Store_MessageID state
*/
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_store_messageid() {
/* Tell ProtocolTX to discard the message being transmitted */
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_DISCARD);
/* Update the stored MessageID */
_rx_messageid = PD_MESSAGEID_GET(&tempMessage);
/* Pass the message to the policy engine. */
PolicyEngine::handleMessage(&tempMessage);
PolicyEngine::notify(PDB_EVT_PE_MSG_RX);
taskYIELD();
/* Don't check if we got a RESET because we'd do nothing different. */
return PRLRxWaitPHY;
}
void ProtocolReceive::init() {
osThreadStaticDef(protRX, thread, PDB_PRIO_PRL, 0, TaskStackSize,
TaskBuffer, &TaskControlBlock);
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
TaskHandle = osThreadCreate(osThread(protRX), NULL);
}
void ProtocolReceive::thread(const void *args) {
(void) args;
ProtocolReceive::protocol_rx_state state = PRLRxWaitPHY;
while (true) {
switch (state) {
case PRLRxWaitPHY:
state = protocol_rx_wait_phy();
break;
case PRLRxReset:
state = protocol_rx_reset();
break;
case PRLRxCheckMessageID:
state = protocol_rx_check_messageid();
break;
case PRLRxStoreMessageID:
state = protocol_rx_store_messageid();
break;
default:
/* This is an error. It really shouldn't happen. We might
* want to handle it anyway, though. */
state = PRLRxWaitPHY;
break;
}
}
}
void ProtocolReceive::notify(uint32_t notification) {
if (xEventGroupHandle != NULL) {
xEventGroupSetBits(xEventGroupHandle, notification);
}
}
uint32_t ProtocolReceive::waitForEvent(uint32_t mask, uint32_t ticksToWait) {
if (xEventGroupHandle != NULL) {
return xEventGroupWaitBits(xEventGroupHandle, mask, mask,
pdFALSE, ticksToWait);
}
return 0;
}

View File

@@ -0,0 +1,64 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PDB_PROTOCOL_RX_H
#define PDB_PROTOCOL_RX_H
#include <stdint.h>
#include <pd.h>
/* Events for the Protocol RX thread */
#define PDB_EVT_PRLRX_RESET EVENT_MASK(0)
#define PDB_EVT_PRLRX_I_GCRCSENT EVENT_MASK(1)
#define PDB_EVT_PRLRX_I_RXPEND EVENT_MASK(2)
class ProtocolReceive {
public:
static void init();
static void notify(uint32_t notification);
private:
static void thread(const void *args);
static EventGroupHandle_t xEventGroupHandle;
static StaticEventGroup_t xCreatedEventGroup;
static osThreadId TaskHandle;
static const size_t TaskStackSize = 1024 / 4;
static uint32_t TaskBuffer[TaskStackSize];
static osStaticThreadDef_t TaskControlBlock;
/*
* Protocol RX machine states
*
* There is no Send_GoodCRC state because the PHY sends the GoodCRC for us.
* All transitions that would go to that state instead go to Check_MessageID.
*/
enum protocol_rx_state {
PRLRxWaitPHY, PRLRxReset, PRLRxCheckMessageID, PRLRxStoreMessageID
};
static protocol_rx_state protocol_rx_store_messageid();
static protocol_rx_state protocol_rx_check_messageid();
static protocol_rx_state protocol_rx_reset();
static protocol_rx_state protocol_rx_wait_phy();
static union pd_msg tempMessage;
static uint8_t _rx_messageid;
static uint8_t _tx_messageidcounter;
static uint32_t waitForEvent(uint32_t mask, uint32_t ticksToWait =
portMAX_DELAY);
};
#endif /* PDB_PROTOCOL_RX_H */

View File

@@ -0,0 +1,298 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "protocol_tx.h"
#include <pd.h>
#include "policy_engine.h"
#include "protocol_rx.h"
#include "fusb302b.h"
#include "fusbpd.h"
osThreadId ProtocolTransmit::TaskHandle = NULL;
uint32_t ProtocolTransmit::TaskBuffer[ProtocolTransmit::TaskStackSize];
osStaticThreadDef_t ProtocolTransmit::TaskControlBlock;
StaticQueue_t ProtocolTransmit::xStaticQueue;
bool ProtocolTransmit::messageSending = false;
uint8_t ProtocolTransmit::ucQueueStorageArea[PDB_MSG_POOL_SIZE
* sizeof(union pd_msg)];
QueueHandle_t ProtocolTransmit::messagesWaiting = NULL;
uint8_t ProtocolTransmit::_tx_messageidcounter;
union pd_msg ProtocolTransmit::temp_msg;
EventGroupHandle_t ProtocolTransmit::xEventGroupHandle = NULL;
StaticEventGroup_t ProtocolTransmit::xCreatedEventGroup;
/*
* PRL_Tx_PHY_Layer_Reset state
*/
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_phy_reset() {
/* Reset the PHY */
fusb_reset();
/* If a message was pending when we got here, tell the policy engine that
* we failed to send it */
if (messagePending()) {
/* Tell the policy engine that we failed */
PolicyEngine::notify( PDB_EVT_PE_TX_ERR);
/* Finish failing to send the message */
while (messagePending()) {
getMessage(); //Discard
}
}
/* Wait for a message request */
return PRLTxWaitMessage;
}
/*
* PRL_Tx_Wait_for_Message_Request state
*/
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_message() {
/* Wait for an event */
ProtocolTransmit::Notifications evt = waitForEvent(
(uint32_t) Notifications::PDB_EVT_PRLTX_RESET
| (uint32_t) Notifications::PDB_EVT_PRLTX_DISCARD
| (uint32_t) Notifications::PDB_EVT_PRLTX_MSG_TX);
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_RESET) {
return PRLTxPHYReset;
}
/* If the policy engine is trying to send a message */
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_MSG_TX) {
/* Get the message */
getMessage();
/* If it's a Soft_Reset, reset the TX layer first */
if (PD_MSGTYPE_GET(&temp_msg) == PD_MSGTYPE_SOFT_RESET
&& PD_NUMOBJ_GET(&(temp_msg)) == 0) {
return PRLTxReset;
/* Otherwise, just send the message */
} else {
return PRLTxConstructMessage;
}
}
/* Silence the compiler warning */
return PRLTxWaitMessage;
}
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_reset() {
/* Clear MessageIDCounter */
_tx_messageidcounter = 0;
/* Tell the Protocol RX thread to reset */
ProtocolReceive::notify( PDB_EVT_PRLRX_RESET);
taskYIELD();
return PRLTxConstructMessage;
}
/*
* PRL_Tx_Construct_Message state
*/
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_construct_message() {
/* Set the correct MessageID in the message */
temp_msg.hdr &= ~PD_HDR_MESSAGEID;
temp_msg.hdr |= (_tx_messageidcounter % 8) << PD_HDR_MESSAGEID_SHIFT;
/* PD 3.0 collision avoidance */
// if (PolicyEngine::isPD3_0()) {
// /* If we're starting an AMS, wait for permission to transmit */
// evt = waitForEvent((uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS,
// 0);
// if ((uint32_t) evt
// & (uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS) {
// while (fusb_get_typec_current() != fusb_sink_tx_ok) {
// osDelay(1);
// }
// }
// }
messageSending = true;
/* Send the message to the PHY */
fusb_send_message(&temp_msg);
return PRLTxWaitResponse;
}
/*
* PRL_Tx_Wait_for_PHY_Response state
*/
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_response() {
/* Wait for an event. There is no need to run CRCReceiveTimer, since the
* FUSB302B handles that as part of its retry mechanism. */
ProtocolTransmit::Notifications evt = waitForEvent(
(uint32_t) Notifications::PDB_EVT_PRLTX_RESET
| (uint32_t) Notifications::PDB_EVT_PRLTX_DISCARD
| (uint32_t) Notifications::PDB_EVT_PRLTX_I_TXSENT
| (uint32_t) Notifications::PDB_EVT_PRLTX_I_RETRYFAIL);
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_RESET) {
return PRLTxPHYReset;
}
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_DISCARD) {
return PRLTxDiscardMessage;
}
/* If the message was sent successfully */
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_I_TXSENT) {
return PRLTxMatchMessageID;
}
/* If the message failed to be sent */
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_I_RETRYFAIL) {
return PRLTxTransmissionError;
}
/* Silence the compiler warning */
return PRLTxDiscardMessage;
}
/*
* PRL_Tx_Match_MessageID state
*/
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_match_messageid() {
union pd_msg goodcrc;
/* Read the GoodCRC */
fusb_read_message(&goodcrc);
/* Check that the message is correct */
if (PD_MSGTYPE_GET(&goodcrc) == PD_MSGTYPE_GOODCRC
&& PD_NUMOBJ_GET(&goodcrc) == 0
&& PD_MESSAGEID_GET(&goodcrc) == _tx_messageidcounter) {
return PRLTxMessageSent;
} else {
return PRLTxTransmissionError;
}
}
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_transmission_error() {
/* Increment MessageIDCounter */
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
/* Tell the policy engine that we failed */
PolicyEngine::notify( PDB_EVT_PE_TX_ERR);
return PRLTxWaitMessage;
}
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_message_sent() {
messageSending = false;
/* Increment MessageIDCounter */
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
/* Tell the policy engine that we succeeded */
PolicyEngine::notify( PDB_EVT_PE_TX_DONE);
return PRLTxWaitMessage;
}
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_discard_message() {
/* If we were working on sending a message, increment MessageIDCounter */
if (messageSending) {
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
return PRLTxPHYReset;
} else {
return PRLTxWaitMessage;
}
}
void ProtocolTransmit::thread(const void *args) {
(void) args;
ProtocolTransmit::protocol_tx_state state = PRLTxPHYReset;
//Init the incoming message queue
while (true) {
switch (state) {
case PRLTxPHYReset:
state = protocol_tx_phy_reset();
break;
case PRLTxWaitMessage:
state = protocol_tx_wait_message();
break;
case PRLTxReset:
state = protocol_tx_reset();
break;
case PRLTxConstructMessage:
state = protocol_tx_construct_message();
break;
case PRLTxWaitResponse:
state = protocol_tx_wait_response();
break;
case PRLTxMatchMessageID:
state = protocol_tx_match_messageid();
break;
case PRLTxTransmissionError:
state = protocol_tx_transmission_error();
break;
case PRLTxMessageSent:
state = protocol_tx_message_sent();
break;
case PRLTxDiscardMessage:
state = protocol_tx_discard_message();
break;
default:
state = PRLTxPHYReset;
break;
}
}
}
void ProtocolTransmit::notify(ProtocolTransmit::Notifications notification) {
if (xEventGroupHandle != NULL) {
xEventGroupSetBits(xEventGroupHandle, (uint32_t) notification);
}
}
void ProtocolTransmit::init() {
messagesWaiting = xQueueCreateStatic(PDB_MSG_POOL_SIZE,
sizeof(union pd_msg), ucQueueStorageArea, &xStaticQueue);
osThreadStaticDef(pd_txTask, thread, PDB_PRIO_PRL, 0, TaskStackSize,
TaskBuffer, &TaskControlBlock);
TaskHandle = osThreadCreate(osThread(pd_txTask), NULL);
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
}
void ProtocolTransmit::pushMessage(union pd_msg *msg) {
if (messagesWaiting) {
xQueueSend(messagesWaiting, msg, 100);
}
}
bool ProtocolTransmit::messagePending() {
if (messagesWaiting) {
return uxQueueMessagesWaiting(messagesWaiting) > 0;
}
return false;
}
void ProtocolTransmit::getMessage() {
//Loads the pending message into the buffer
if (messagesWaiting) {
xQueueReceive(messagesWaiting, &temp_msg, 1);
}
}
ProtocolTransmit::Notifications ProtocolTransmit::waitForEvent(uint32_t mask,
uint32_t ticksToWait) {
if (xEventGroupHandle) {
return (Notifications) xEventGroupWaitBits(xEventGroupHandle, mask,
mask,
pdFALSE, ticksToWait);
}
return (Notifications)0;
}

View File

@@ -0,0 +1,97 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PDB_PROTOCOL_TX_H
#define PDB_PROTOCOL_TX_H
#include <stdint.h>
#include "policy_engine.h"
#include "protocol_rx.h"
#include <pd.h>
/* Events for the Protocol TX thread */
class ProtocolTransmit {
public:
static void init();
//Push a message to the queue to be sent out the pd comms bus
static void pushMessage(union pd_msg *msg);
enum class Notifications {
PDB_EVT_PRLTX_RESET = EVENT_MASK(0), //
PDB_EVT_PRLTX_I_TXSENT = EVENT_MASK(1), //
PDB_EVT_PRLTX_I_RETRYFAIL = EVENT_MASK(2), //
PDB_EVT_PRLTX_DISCARD = EVENT_MASK(3), //
PDB_EVT_PRLTX_MSG_TX = EVENT_MASK(4), //
PDB_EVT_PRLTX_START_AMS = EVENT_MASK(5), //
};
static void notify(Notifications notification);
private:
static void thread(const void *args);
static EventGroupHandle_t xEventGroupHandle;
static StaticEventGroup_t xCreatedEventGroup;
static osThreadId TaskHandle;
static const size_t TaskStackSize = 1024 / 4;
static uint32_t TaskBuffer[TaskStackSize];
static osStaticThreadDef_t TaskControlBlock;
static bool messageSending;
/*
* Protocol TX machine states
*
* Because the PHY can automatically send retries, the Check_RetryCounter state
* has been removed, transitions relating to it are modified appropriately, and
* we don't even keep a RetryCounter.
*/
enum protocol_tx_state {
PRLTxPHYReset,
PRLTxWaitMessage,
PRLTxReset,
PRLTxConstructMessage,
PRLTxWaitResponse,
PRLTxMatchMessageID,
PRLTxTransmissionError,
PRLTxMessageSent,
PRLTxDiscardMessage
};
//Internal states
static protocol_tx_state protocol_tx_discard_message();
static protocol_tx_state protocol_tx_message_sent();
static protocol_tx_state protocol_tx_transmission_error();
static protocol_tx_state protocol_tx_match_messageid();
static protocol_tx_state protocol_tx_wait_response();
static protocol_tx_state protocol_tx_construct_message();
static protocol_tx_state protocol_tx_reset();
static protocol_tx_state protocol_tx_wait_message();
static protocol_tx_state protocol_tx_phy_reset();
//queue of up to PDB_MSG_POOL_SIZE messages to send
static StaticQueue_t xStaticQueue;
/* The array to use as the queue's storage area. This must be at least
uxQueueLength * uxItemSize bytes. */
static uint8_t ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)];
static QueueHandle_t messagesWaiting;
static uint8_t _tx_messageidcounter;
static bool messagePending();
//Reads a message off the queue into the temp message
static void getMessage();
static union pd_msg temp_msg;
static Notifications waitForEvent(uint32_t mask, uint32_t ticksToWait =
portMAX_DELAY);
};
#endif /* PDB_PROTOCOL_TX_H */

View File

@@ -126,18 +126,6 @@ const uint8_t idleScreenBG[] = {
0x8A,0x84,0x82,0x81,0x80,0x80,0x80,0x40,0x40,0x20,0x18,0x07
};
const uint8_t idleScreenBGF[] = {
//width = 84
//height = 16
0xE0,0x18,0x04,0x02,0x02,0x01,0x41,0x81,0x01,0x01,0x65,0x99,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x04,0x18,0xE0,0x00,0x00,0xE0,0x18,0x04,0x02,0x02,
0x01,0x01,0x41,0x61,0x61,0x61,0xE1,0xC1,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0xC1,
0xE1,0x61,0x61,0x61,0x41,0x01,0x02,0x02,0x04,0x18,0xE0,0x00,
0x07,0x18,0x20,0x40,0x40,0x80,0x80,0x80,0x81,0x82,0x84,0x8A,0x92,0x82,0x82,0x82,0x80,0x82,0x80,0x82,0x82,0x82,0x87,0x87,
0x85,0x87,0x85,0x87,0x87,0x85,0x85,0x85,0x85,0x87,0x82,0x80,0x40,0x40,0x20,0x18,0x07,0x00,0x00,0x07,0x18,0x20,0x40,0x40,
0x80,0x80,0x82,0x86,0x86,0x86,0x87,0x83,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x83,
0x87,0x86,0x86,0x86,0x82,0x80,0x40,0x40,0x20,0x18,0x07,0x00
};
/*
* 16x16 icons

View File

@@ -0,0 +1,313 @@
/*
* I2CBB.cpp
*
* Created on: 12 Jun 2020
* Author: Ralim
*/
#include "Model_Config.h"
#ifdef I2C_SOFT
#include <I2CBB.hpp>
#include "FreeRTOS.h"
SemaphoreHandle_t I2CBB::I2CSemaphore = NULL;
StaticSemaphore_t I2CBB::xSemaphoreBuffer;
SemaphoreHandle_t I2CBB::I2CSemaphore2 = NULL;
StaticSemaphore_t I2CBB::xSemaphoreBuffer2;
void I2CBB::init() {
//Set GPIO's to output open drain
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Pin = SDA2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(SDA2_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Pin = SCL2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(SCL2_GPIO_Port, &GPIO_InitStruct);
SOFT_SDA_HIGH();
SOFT_SCL_HIGH();
I2CSemaphore = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer);
I2CSemaphore2 = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer2);
unlock();
unlock2();
}
bool I2CBB::probe(uint8_t address) {
if (!lock())
return false;
start();
bool ack = send(address);
stop();
unlock();
return ack;
}
bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
uint16_t Size) {
if (!lock())
return false;
start();
bool ack = send(DevAddress);
if (!ack) {
stop();
unlock();
return false;
}
ack = send(MemAddress);
if (!ack) {
stop();
unlock();
return false;
}
SOFT_SCL_LOW();
SOFT_I2C_DELAY();
// stop();
start();
ack = send(DevAddress | 1);
if (!ack) {
stop();
unlock();
return false;
}
while (Size) {
pData[0] = read(Size > 1);
pData++;
Size--;
}
stop();
unlock();
return true;
}
bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
const uint8_t *pData, uint16_t Size) {
if (!lock())
return false;
start();
bool ack = send(DevAddress);
if (!ack) {
stop();
asm("bkpt");
unlock();
return false;
}
ack = send(MemAddress);
if (!ack) {
stop();
asm("bkpt");
unlock();
return false;
}
while (Size) {
resetWatchdog();
ack = send(pData[0]);
if (!ack) {
stop();
asm("bkpt");
unlock();
return false;
}
pData++;
Size--;
}
stop();
unlock();
return true;
}
void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
if (!lock())
return;
start();
bool ack = send(DevAddress);
if (!ack) {
stop();
unlock();
return;
}
while (Size) {
ack = send(pData[0]);
if (!ack) {
stop();
unlock();
return;
}
pData++;
Size--;
}
stop();
unlock();
}
void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
if (!lock())
return;
start();
bool ack = send(DevAddress | 1);
if (!ack) {
stop();
unlock();
return;
}
while (Size) {
pData[0] = read(Size > 1);
pData++;
Size--;
}
stop();
unlock();
}
void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) {
if (Size_tx == 0 && Size_rx == 0)
return;
if (lock() == false)
return;
if (Size_tx) {
start();
bool ack = send(DevAddress);
if (!ack) {
stop();
unlock();
return;
}
while (Size_tx) {
ack = send(pData_tx[0]);
if (!ack) {
stop();
unlock();
return;
}
pData_tx++;
Size_tx--;
}
}
if (Size_rx) {
start();
bool ack = send(DevAddress | 1);
if (!ack) {
stop();
unlock();
return;
}
while (Size_rx) {
pData_rx[0] = read(Size_rx > 1);
pData_rx++;
Size_rx--;
}
}
stop();
unlock();
}
void I2CBB::start() {
/* I2C Start condition, data line goes low when clock is high */
SOFT_SCL_HIGH();
SOFT_SDA_HIGH();
SOFT_I2C_DELAY();
SOFT_SDA_LOW();
SOFT_I2C_DELAY();
SOFT_SCL_LOW();
SOFT_I2C_DELAY();
SOFT_SDA_HIGH();
}
void I2CBB::stop() {
/* I2C Stop condition, clock goes high when data is low */
SOFT_SDA_LOW();
SOFT_I2C_DELAY();
SOFT_SCL_HIGH();
SOFT_I2C_DELAY();
SOFT_SDA_HIGH();
SOFT_I2C_DELAY();
}
bool I2CBB::send(uint8_t value) {
for (uint8_t i = 0; i < 8; i++) {
write_bit(value & 0x80); // write the most-significant bit
value <<= 1;
}
SOFT_SDA_HIGH();
bool ack = (read_bit() == 0);
return ack;
}
uint8_t I2CBB::read(bool ack) {
uint8_t B = 0;
uint8_t i;
for (i = 0; i < 8; i++) {
B <<= 1;
B |= read_bit();
}
SOFT_SDA_HIGH();
if (ack)
write_bit(0);
else
write_bit(1);
return B;
}
uint8_t I2CBB::read_bit() {
uint8_t b;
SOFT_SDA_HIGH();
SOFT_I2C_DELAY();
SOFT_SCL_HIGH();
SOFT_I2C_DELAY();
if (SOFT_SDA_READ())
b = 1;
else
b = 0;
SOFT_SCL_LOW();
return b;
}
void I2CBB::unlock() {
xSemaphoreGive(I2CSemaphore);
}
bool I2CBB::lock() {
if (I2CSemaphore == NULL) {
asm("bkpt");
}
bool a = xSemaphoreTake(I2CSemaphore, (TickType_t) 100) == pdTRUE;
return a;
}
void I2CBB::write_bit(uint8_t val) {
if (val) {
SOFT_SDA_HIGH();
} else {
SOFT_SDA_LOW();
}
SOFT_I2C_DELAY();
SOFT_SCL_HIGH();
SOFT_I2C_DELAY();
SOFT_SCL_LOW();
}
void I2CBB::unlock2() {
xSemaphoreGive(I2CSemaphore2);
}
bool I2CBB::lock2() {
if (I2CSemaphore2 == NULL) {
asm("bkpt");
}
bool a = xSemaphoreTake(I2CSemaphore2, (TickType_t) 500) == pdTRUE;
return a;
}
#endif

View File

@@ -0,0 +1,51 @@
/*
* I2CBB.hpp
*
* Created on: 12 Jun 2020
* Author: Ralim
*/
#ifndef BSP_MINIWARE_I2CBB_HPP_
#define BSP_MINIWARE_I2CBB_HPP_
#include "Model_Config.h"
#ifdef I2C_SOFT
#include "BSP.h"
#include "Setup.h"
#include "Pins.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "Software_I2C.h"
class I2CBB {
public:
static void init();
//Probe if device ACK's address or not
static bool probe(uint8_t address);
//Issues a complete 8bit register read
static bool Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size);
//Implements a register write
static bool Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
const uint8_t *pData, uint16_t Size);
static void Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
static void Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
static void TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx);
static void unlock2();
static bool lock2();
private:
static SemaphoreHandle_t I2CSemaphore;
static StaticSemaphore_t xSemaphoreBuffer;
static SemaphoreHandle_t I2CSemaphore2;
static StaticSemaphore_t xSemaphoreBuffer2;
static void unlock();
static bool lock();
static void start();
static void stop();
static bool send(uint8_t value);
static uint8_t read(bool ack);
static uint8_t read_bit();
static void write_bit(uint8_t val);
};
#endif
#endif /* BSP_MINIWARE_I2CBB_HPP_ */

View File

@@ -21,10 +21,6 @@
class FRToSI2C {
public:
static void init() {
I2CSemaphore = nullptr;
}
static void FRToSInit() {
I2CSemaphore = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer);
xSemaphoreGive(I2CSemaphore);
@@ -34,16 +30,21 @@ public:
static bool Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size);
static void Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
static bool Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size);
//Returns true if device ACK's being addressed
static bool probe(uint16_t DevAddress);
static void Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
static void I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data);
static bool Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
static void Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
static void TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx);
static bool I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data);
static uint8_t I2C_RegisterRead(uint8_t address, uint8_t reg);
private:
static void unlock();
static bool lock();
static void I2C_Unstick();
static SemaphoreHandle_t I2CSemaphore;
static StaticSemaphore_t xSemaphoreBuffer;

View File

@@ -171,7 +171,7 @@ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) {
while (duration <= totalDuration) {
duration = xTaskGetTickCount() - start;
uint8_t progress = duration * 100 / totalDuration;
uint8_t progress = duration * 1000 / totalDuration;
progress = easeInOutTiming(progress);
progress = lerp(0, OLED_WIDTH, progress);
if (progress > OLED_WIDTH) {
@@ -191,9 +191,9 @@ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) {
offset = progress;
memmove(&firstStripPtr[oldStart], &firstStripPtr[oldPrevious],
OLED_WIDTH - progress);
OLED_WIDTH - progress);
memmove(&secondStripPtr[oldStart], &secondStripPtr[oldPrevious],
OLED_WIDTH - progress);
OLED_WIDTH - progress);
memmove(&firstStripPtr[newStart], &firstBackStripPtr[newEnd], progress);
memmove(&secondStripPtr[newStart], &secondBackStripPtr[newEnd],
@@ -213,7 +213,7 @@ void OLED::useSecondaryFramebuffer(bool useSecondary) {
}
void OLED::setRotation(bool leftHanded) {
#ifdef MODEL_TS80
#ifdef OLED_FLIP
leftHanded = !leftHanded;
#endif
if (inLeftHandedMode == leftHanded) {

View File

@@ -27,12 +27,11 @@
* This was bought to my attention by <Kuba Sztandera>
*/
uint32_t TipThermoModel::convertTipRawADCTouV(uint16_t rawADC) {
// This takes the raw ADC samples, converts these to uV
// Then divides this down by the gain to convert to the uV on the input to the op-amp (A+B terminals)
// Then remove the calibration value that is stored as a tip offset
uint32_t vddRailmVX10 = 33000; //The vreg is +-2%, but we have no higher accuracy available
uint32_t vddRailmVX10 = 33000;//The vreg is +-2%, but we have no higher accuracy available
// 4096 * 8 readings for full scale
// Convert the input ADC reading back into mV times 10 format.
uint32_t rawInputmVX10 = (rawADC * vddRailmVX10) / (4096 * 8);
@@ -76,7 +75,7 @@ uint32_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) {
tipuVDelta *= 10;
tipuVDelta /= systemSettings.TipGain;
#ifdef MODEL_TS80
#if defined( MODEL_TS80)+defined( MODEL_TS80P)>0
tipuVDelta /= OP_AMP_GAIN_STAGE_TS100 / OP_AMP_GAIN_STAGE_TS80;
#endif

View File

@@ -1,173 +1,171 @@
/*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS 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. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* Section where include file can be added */
/* USER CODE END Includes */
/* Ensure stdint is only used by the compiler, and not the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
#define configUSE_PREEMPTION 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 0
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ((TickType_t)100)
#define configMAX_PRIORITIES ( 4 )
#define configMINIMAL_STACK_SIZE ((uint16_t)256)
#define configTOTAL_HEAP_SIZE ((size_t)1024*14) /*Currently use about 9000*/
#define configMAX_TASK_NAME_LEN ( 24 )
#define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configCHECK_FOR_STACK_OVERFLOW 2 /*Bump this to 2 during development and bug hunting*/
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 0
#define INCLUDE_vTaskDelayUntil 0
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
/* USER CODE END 1 */
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
/* IMPORTANT: This define MUST be commented when used with STM32Cube firmware,
to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
/* #define xPortSysTickHandler SysTick_Handler */
/* USER CODE BEGIN Defines */
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
/* USER CODE END Defines */
#endif /* FREERTOS_CONFIG_H */
/*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS 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. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* Section where include file can be added */
/* USER CODE END Includes */
/* Ensure stdint is only used by the compiler, and not the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
#define configUSE_PREEMPTION 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 0
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES ( 6 )
#define configMINIMAL_STACK_SIZE ((uint16_t)256)
#define configTOTAL_HEAP_SIZE ((size_t)1024*14) /*Currently use about 9000*/
#define configMAX_TASK_NAME_LEN ( 32 )
#define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configUSE_TIMERS 0
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configCHECK_FOR_STACK_OVERFLOW 2 /*Bump this to 2 during development and bug hunting*/
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 0
#define INCLUDE_vTaskDelayUntil 0
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
/* USER CODE END 1 */
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#if configUSE_TIMERS
#define configTIMER_TASK_PRIORITY 2
#define configTIMER_QUEUE_LENGTH 8
#define configTIMER_TASK_STACK_DEPTH (512/4)
#endif
#endif /* FREERTOS_CONFIG_H */

View File

@@ -12,7 +12,7 @@
#include <stdint.h>
#include "stm32f1xx_hal.h"
#include "unit.h"
#define SETTINGSVERSION ( 0x20 )
#define SETTINGSVERSION ( 0x21 )
/*Change this if you change the struct below to prevent people getting \
out of sync*/
@@ -32,8 +32,7 @@ typedef struct {
uint8_t autoStartMode :2; // Should the unit automatically jump straight
// into soldering mode when power is applied
uint8_t ShutdownTime; // Time until unit shuts down if left alone
uint8_t boostModeEnabled :1; // Boost mode swaps BUT_A in soldering mode to
// temporary soldering temp over-ride
uint8_t coolingTempBlink :1; // Should the temperature blink on the cool
// down screen until its <50C
uint8_t detailedIDLE :1; // Detailed idle screen
@@ -49,7 +48,6 @@ typedef struct {
uint16_t CalibrationOffset; // This stores the temperature offset for this tip
// in the iron.
uint8_t powerLimitEnable; // Allow toggling of power limit without changing value
uint8_t powerLimit; // Maximum power iron allowed to output
uint16_t TipGain; // uV/C * 10, it can be used to convert tip thermocouple voltage to temperateture TipV/TipGain = TipTemp

View File

@@ -9,16 +9,12 @@
#define TRANSLATION_H_
#include "unit.h"
#include "stdint.h"
enum ShortNameType {
SHORT_NAME_SINGLE_LINE = 1, SHORT_NAME_DOUBLE_LINE = 2,
};
extern const uint8_t USER_FONT_12[];
extern const uint8_t USER_FONT_6x8[];
/*
* When SettingsShortNameType is SHORT_NAME_SINGLE_LINE
* use SettingsShortNames as SettingsShortNames[16][1].. second column undefined
*/
extern const enum ShortNameType SettingsShortNameType;
extern const char *SettingsShortNames[28][2];
extern const char *SettingsDescriptions[28];
extern const char *SettingsMenuEntries[4];

View File

@@ -11,24 +11,20 @@
#include "Settings.h"
#include "BSP.h"
#define PRESS_ACCEL_STEP 3
#define PRESS_ACCEL_INTERVAL_MIN 10
#define PRESS_ACCEL_INTERVAL_MAX 30
#define PRESS_ACCEL_STEP 30
#define PRESS_ACCEL_INTERVAL_MIN 100
#define PRESS_ACCEL_INTERVAL_MAX 300
//GUI holds the menu structure and all its methods for the menu itself
//Declarations for all the methods for the settings menu (at end of this file)
//Wrapper for holding a function pointer
typedef struct state_func_t {
void (*func)(void);
} state_func;
//Struct for holding the function pointers and descriptions
typedef struct {
const char *description;
const state_func incrementHandler;
const state_func draw;
// return true if increment reached the maximum value
bool (* const incrementHandler)(void);
void (* const draw)(void);
} menuitem;
void enterSettingsMenu();

View File

@@ -6,18 +6,11 @@
extern uint8_t PCBVersion;
extern uint32_t currentTempTargetDegC;
extern bool settingsWereReset;
extern bool usb_pd_available;
#ifdef __cplusplus
extern "C" {
#endif
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc);
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
void vApplicationStackOverflowHook(xTaskHandle *pxTask,
signed portCHAR *pcTaskName);

View File

@@ -9,6 +9,7 @@
#include <history.hpp>
#include "BSP.h"
#include "expMovingAverage.h"
#include "../../configuration.h"
#ifndef POWER_HPP_
#define POWER_HPP_
@@ -18,16 +19,6 @@
// This is necessary because of the temp noise and thermal lag in the system.
// Once we have feed-forward temp estimation we should be able to better tune this.
#ifdef MODEL_TS100
const int32_t tipMass = 45; // X10 watts to raise 1 deg C in 1 second
const uint8_t tipResistance = 85; //x10 ohms, 8.5 typical for ts100, 4.5 typical for ts80
#endif
#ifdef MODEL_TS80
const uint32_t tipMass = 40;
const uint8_t tipResistance = 45; //x10 ohms, 8.5 typical for ts100, 4.5 typical for ts80
#endif
const uint8_t wattHistoryFilter = 24; // I term look back weighting
extern expMovingAverage<uint32_t, wattHistoryFilter> x10WattHistory;

Some files were not shown because too many files have changed in this diff Show More