├── .gitignore ├── README.md ├── bin ├── bootloader.bin ├── firmware12_201.bin ├── firmware24_201.bin ├── firmware_202.bin ├── firmware_203.bin ├── firmware_beta.bin ├── manifest_12.json ├── manifest_24.json ├── manifest_beta.json ├── manifest_v202.json ├── manifest_v203.json └── partitions.bin ├── images ├── a.html ├── ap01.png ├── ap02.png ├── ap03.png ├── s14-12-24_00.JPG ├── s14-24-12_01.JPG ├── s14-24-12_04.JPG ├── s14_back.JPG ├── s14_parts.JPG ├── s14clk_parts.JPG ├── s14web_01a.png └── s14web_02.png ├── index.md ├── install.html ├── platformio.ini ├── s14clock_firmware ├── map.h ├── s14clock_firmware.ino ├── ver1.h ├── ver2.h ├── ver2l.h ├── ver3.h ├── zf.pl └── zf1.pl └── zgen.pl /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .DS_Store 3 | *~ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # S14Clock 2 | 3 | [Install v2.04 beta firmware, pick firmware beta](https://simpleavr.github.io/s14clock/install.html) 4 | 5 | **2025-01-05** Fix hardware version detection, V2-24 hardware detection was broken. 6 | 7 | **2024-05-02** Change 'alternate transition' token from '\~=' to '\~!'. '\~=' be used in new "exact date" macro, '\~=0501?HAPPY MAYDAY'. Implement alternate transition for "flip" to flip also spaces. Implement alternate transition for "flash" to use alternate sequence. 8 | 9 | **2023-12-10** Implements "alternate transition"" macro, `'\~='`. I.e. double-blink for **Blink** transition, left-to-right for **Shift** and **Drip** transitions, and alternate sequence for other transitions. 10 | 11 | **2023-12-07** Implements "day counting" macro, `'\~MMDD? DAYS SINCE ..'`, apart from MMDD, YYMMDD and YYYYMMDD also accepted. Capable of counting up to 40+ years due to datatype constraint. When using MMDD, system assumes past, current, or next year as reference automatically. 12 | 13 | [Install latest firmware, pick v2.03](https://simpleavr.github.io/s14clock/install.html) 14 | 15 | **2023-11-27** NTP server and POSIX TZ configuration changed from using 8th content slot to a new storage space. The new fields are 40 characters wide and 16 | should be able to hold the extra long TZ strings. 17 | 18 | **2023-11-08** V2.03 Add optional POSIX TZ configuration support. This will allow daylight saving time configurations (eg. EST5EDT,M3.2.0,M11.1.0). Enter POSIX TZ string as the 8th "Additional Content" text, prefixed with '@' character, and make sure the "Use" checkbox is off. Example enter "@EST5EDT" as the 8th display addn text. Configuration web page will now also detect geo-location and suggest a proper TZ value to use. Feature available in bin/firmware_203.bin 19 | 20 | **2023-07-25** Implement new content tokens `'\~+dd'` and `'\~-dd'` to adjust current time by adding / subtracting hours, useful for multi-city display. 21 | 22 | **2023-06-25** Implement configurable NTP server, to configure, enter overriding NTP server url as the 8th "Display Content" text, prefixed with '@' character, and make sure the "Use" checkbox is off. Example enter "@time2.google.com" as the 8th display content text. 23 | 24 | **2023-06-12** Added to main branch are 2 startup options, press-n-hold button '0' during "0000..." test screen allow resetting WIFI credentials, pressing button '0' during "FW... HW.." version display enters Burn-In mode without setup, which excercise the time showing routines without WIFI. 25 | 26 | **2023-06-07** V2.02 common firmware auto-detects and support all (V3, V2-24, V2-12) hardware designs. V3 hardware design eliminates 74HC154 4-to-16 line decoder. V2.02 software adds charliplexing to V2.01 led multiplexing scheme and achieves 14 x 24 (336 segments) direct driving with 26 IO pins. 27 | 28 | S14Clock is a bar shaped, web synchronized word clock featuring 24 or 12 characters, 14 segment display. 29 | 30 | [Project description](https://simpleavr.github.io/s14clock/index.html) 31 | 32 | [Project wiki page, tips on building](https://github.com/simpleavr/s14clock/wiki.html) 33 | 34 | [Project discussion page, questions and comments](https://github.com/simpleavr/s14clock/discussions.html) 35 | 36 | [Install firmware](https://simpleavr.github.io/s14clock/install.html) 37 | 38 | [Unit can be obtained from store139 in tindie](https://www.tindie.com/products/29601/) 39 | 40 | Build using Arduino or PlatformIO. 41 | 42 | S14Clock relies on Arduino AutoConnect library by Hieromon. 43 | If using Arduino to build, make sure you install the library first. 44 | 45 | [Download as **.zip**](https://github.com/simpleavr/s14clock/archive/refs/heads/main.zip) or clone the project with `git clone https://github.com/simpleavr/s14clock.git` 46 | 47 | ## Building using Arduino 48 | 49 | - Open the folder `s14clock_firmware`, double click `s14clock_firmware.ino` and it will open in the Arduino IDE 50 | - if you don't yet have support for ESP32 follow [the instructions](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html) to install the platform 51 | - go to Library Manager, search for "AutoConnect" and install the resulting library by "Hieromon Ikasamo" 52 | - select the board ESP32 > ESP32S2 Dev Module 53 | - select the port it is connected to 54 | - press Verify 55 | - if it verifies correctly press Upload 56 | 57 | ## Building with PlatformIO 58 | 59 | - ~~edit src/main.cpp to include "ver2.h" (12 characters version) or "ver2l.h" (24 characters version)~~ 60 | - cd s14clock 61 | - pio project init --board lolin_s2_mini 62 | - pio lib install AutoConnect 63 | - pio run --target upload 64 | 65 | Once installed, follow the guide hosted at the [project description](https://simpleavr.github.io/s14clock/index.html) 66 | 67 | V2.01 firmware (2023-03-20) 68 | 69 | - replace "glow" transition with "drip" transition 70 | - enchange shift transition 71 | 72 | V2.02 firmware (2023-05-29) 73 | 74 | - introduce "flash" transition 75 | - add option to cycle through all transaction modes one after another 76 | - config time with new time zone immediately after change 77 | - autodetect v2, v2l, v3 hardware 78 | - substitute underscore with space for ad-hoc messages 79 | - ad-hoc messages now follows transition in 80 | - implements %-[dmHIMSjuW] tokens in strftime() to suppress leading zeros and spaces 81 | 82 | V2.03 firmware (2023-11-27) 83 | 84 | - implement new content tokens '\~+dd' and '\~-dd' to adjust current time, useful for multi-city display. 85 | - allows NTP server override and POSIX TZ support, allowing standard and daylight saving time switching. 86 | 87 | -------------------------------------------------------------------------------- /bin/bootloader.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/bin/bootloader.bin -------------------------------------------------------------------------------- /bin/firmware12_201.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/bin/firmware12_201.bin -------------------------------------------------------------------------------- /bin/firmware24_201.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/bin/firmware24_201.bin -------------------------------------------------------------------------------- /bin/firmware_202.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/bin/firmware_202.bin -------------------------------------------------------------------------------- /bin/firmware_203.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/bin/firmware_203.bin -------------------------------------------------------------------------------- /bin/firmware_beta.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/bin/firmware_beta.bin -------------------------------------------------------------------------------- /bin/manifest_12.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "S14Clock S14-12 firmware", 3 | "version": "2.01", 4 | "builds": [ 5 | { 6 | "chipFamily": "ESP32-S2", 7 | "new_install_prompt_erase": true, 8 | "parts": [ 9 | { "path": "bootloader.bin", "offset": 4096 }, 10 | { "path": "partitions.bin", "offset": 32768 }, 11 | { "path": "firmware12_201.bin", "offset": 65536 } 12 | ] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /bin/manifest_24.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "S14Clock S14-24 firmware", 3 | "version": "2.01", 4 | "builds": [ 5 | { 6 | "chipFamily": "ESP32-S2", 7 | "new_install_prompt_erase": true, 8 | "parts": [ 9 | { "path": "bootloader.bin", "offset": 4096 }, 10 | { "path": "partitions.bin", "offset": 32768 }, 11 | { "path": "firmware24_201.bin", "offset": 65536 } 12 | ] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /bin/manifest_beta.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "S14Clock beta common firmware", 3 | "version": "beta", 4 | "builds": [ 5 | { 6 | "chipFamily": "ESP32-S2", 7 | "new_install_prompt_erase": false, 8 | "parts": [ 9 | { "path": "bootloader.bin", "offset": 4096 }, 10 | { "path": "partitions.bin", "offset": 32768 }, 11 | { "path": "firmware_beta.bin", "offset": 65536 } 12 | ] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /bin/manifest_v202.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "S14Clock v2.02 common firmware", 3 | "version": "2.02", 4 | "builds": [ 5 | { 6 | "chipFamily": "ESP32-S2", 7 | "new_install_prompt_erase": true, 8 | "parts": [ 9 | { "path": "bootloader.bin", "offset": 4096 }, 10 | { "path": "partitions.bin", "offset": 32768 }, 11 | { "path": "firmware_202.bin", "offset": 65536 } 12 | ] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /bin/manifest_v203.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "S14Clock v2.03 common firmware", 3 | "version": "2.03", 4 | "builds": [ 5 | { 6 | "chipFamily": "ESP32-S2", 7 | "new_install_prompt_erase": true, 8 | "parts": [ 9 | { "path": "bootloader.bin", "offset": 4096 }, 10 | { "path": "partitions.bin", "offset": 32768 }, 11 | { "path": "firmware_203.bin", "offset": 65536 } 12 | ] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /bin/partitions.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/bin/partitions.bin -------------------------------------------------------------------------------- /images/a.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/a.html -------------------------------------------------------------------------------- /images/ap01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/ap01.png -------------------------------------------------------------------------------- /images/ap02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/ap02.png -------------------------------------------------------------------------------- /images/ap03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/ap03.png -------------------------------------------------------------------------------- /images/s14-12-24_00.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/s14-12-24_00.JPG -------------------------------------------------------------------------------- /images/s14-24-12_01.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/s14-24-12_01.JPG -------------------------------------------------------------------------------- /images/s14-24-12_04.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/s14-24-12_04.JPG -------------------------------------------------------------------------------- /images/s14_back.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/s14_back.JPG -------------------------------------------------------------------------------- /images/s14_parts.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/s14_parts.JPG -------------------------------------------------------------------------------- /images/s14clk_parts.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/s14clk_parts.JPG -------------------------------------------------------------------------------- /images/s14web_01a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/s14web_01a.png -------------------------------------------------------------------------------- /images/s14web_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleavr/s14clock/a02ef87ad2eb63d3f90f2df1dfc53e159135e373/images/s14web_02.png -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## S14 Clock 4 | 5 | 6 | 7 | 8 | 9 | **Bar shaped, web synchronized word clock featuring 24 or 12 characters, 14 segment LED display** 10 | 11 | 12 | 13 | 14 | 15 |

16 | 17 | 18 | **2023-06-07** V3 hardware (24 characters) released, 74HC154 eliminated. New circuit design adds charliplexing to led multiplexing to simplify design. No more SMD to solder makes a more robust kit. 19 | 20 | 21 | 22 | 23 | ### Description 24 | 25 | 26 | 27 | This is a web synchronized clock featuring 14 segment LED displays, allowing spelled word time display options, plus various numeric character sets. 28 | 29 | The S14Clock is available for purchase from [store139 in Tindie](https://www.tindie.com/products/29601/). 30 | 31 | If you are building this project, there are additonal tips in the [project wiki page](https://github.com/simpleavr/s14clock/wiki). 32 | 33 | Github repository, [my github repository](https://github.com/simpleavr/s14clock) 34 | 35 | Firmware Installer [click here](./install.html). 36 | 37 | 38 | IMG IMG 39 | 40 | Two versions of 12 (S14-12) and (S14-24) 24 characters were created, with same functionality. The clock offers various display format and optons. It can also be used as an internet display, accepting messages via a web page. 41 | 42 | A single tactile button is used to advance one of the eight present display formats / messages. The same button when pressn-hold allows cycling between various display transition effects. 43 | 44 | A countdown timer can also be activated via double tapping the button. Setup is done via a web interface that allow for 8 preset display formats / messages. 45 | 46 | 47 | 48 | ### Main Features 49 | 50 | 51 | - Web based WIFI setup, upon initial usage. 52 | - Web based configuration, to preset up to 8 display formats or messages. 53 | - Date time formats via strftime() c library standard. 54 | - Ad-hoc message via web page posting. 55 | - Synchronize date time via ntp.org time server. 56 | - Various setting including automatic cycling of messages, alternate numeric symbols, etc. 57 | - Employs ESP32 S2 Mini, with open source code via github. 58 | - S14-24 24 characters dimension 200mm x 32mm x 30mm (approx. 8" x 1-1/4" x 1-1/4") 59 | - S14-12 12 characters dimension 100mm x 30mm x 30mm (approx. 4" x 1-1/4" x 1-1/4") 60 | 61 | ### Technical Details 62 | 63 | - Employs Arduino ESP32 AutoConnect library for entering WIFI credentials. 64 | - Full use of ESP32 S2 Mini IO pins to perform LED multiplexing and charlieplexing. 65 | - Access of IO registers directly and timer interrupts for efficient multiplexing. 66 | 67 | ### Initial Setup 68 | 69 | The device must be connect to your home network in order to gain time server access via the internet. You will need to provide your home network name (SSID) and password via the ESP32 AutoConnect library. 70 | 71 | Power up your S14Clock, you should see the message "CONNECTING" after a brief display checkup. 72 | 73 | IMG 74 | 75 | Use your phone or computer and locate the AP with SSID "ESP-??????", connect with password "12345678". 76 | 77 | Choose from the "3-bar" menu (top right) "Configure new AP" and select your home network. 78 | 79 | Enter your home network WIFI credentials and hit "Apply" button. 80 | 81 | IMG IMG IMG 82 | 83 | 84 | 85 | Your S14Clock should connect to your home network and will start to work after showing it's IP address briefly. You may need to reset the S14Clock via the bottom hardware reset button. 86 | 87 | ### Application Notes (Clock Unit) 88 | 89 | The S14Clock make use of the button on the ESP32 module for local functionalities, at the back of the clock unit, there are 2 buttons, the button marked 'RST' is a power reset button. The button marked '0' is the application button; 90 | 91 | IMG 92 | 93 | - Single press advances (cycles) the 8 preset display format / messages. 94 | - Press-n-hold advances the display transition effect, subsequent presses cycles to the next transition effect. 95 | - Double press in quick succession starts the countdown / countup timer with the present countdown / countup message. Double presses again when clock unit is already in countdown mode will advance the countdown time. Single key press cancels the countdown timer. 96 | 97 | ### Application Notes (Web Server) 98 | 99 | Upon power up the S14Clock will show it's IP address briefly. The S14Clock runs a web server for configuration and customization. Enter the IP address via a browser to access the appliation server. 100 | 101 | The **primary buttons** at the top of the page serves the following purposes; 102 | 103 | - **Count Down** turns the display into a countdown timer, additional press on this button advances the countdown time. 104 | - **Advance Display** cycle to the next display format, as setup via "Display Content" entries. 105 | - **Reset Configuration** resets S14Clock to preset default configuration values. 106 | - **Reset WIFI** forget current WIFI credentials, next power up will require WIFI setup again. 107 | - **Use** button to confirm use of system discovered Posix TZ (timezone) configuration. 108 | 109 | IMG 110 | 111 | **Ad-hoc messages** can be entered and send to the S14Clock display. If entered text is prefixed with ~x or ~X, message will expire in 10 or 60 seconds and clock will return to previous display content. 112 | 113 | Eight sets of **display contents** (left plus right aligned text and tokens) can be configured, along with checkboxes to turn them on and off. The "on" contents will be cycled through the cycle / advance display button. 114 | 115 | 116 | IMG 117 | 118 | A separated **countdown content display** set is used specifically for countdown function. 119 | 120 | Optional **Alternate NTP Server** entry if you want a different or local NTP server setup. 121 | 122 | **Posix TZ** entry, if entered, allows Posix Time Zone string to describe GMT offset, daylight saving time details, this can be populated automatically from the **Use** button at the top of the page after user verify the zone discovery result is reasonable. 123 | 124 | Tokens are used to substitute current date time elements and also font used. Their usage can be found in the "Format Control" section below. 125 | 126 | The rest of the configuration parameters are self explainary. Countdown Increments, Transit Effects, Cycle Seconds (0 for no content cycling), Brightness, Rotate (when display is turn upside down), All Caps, Auresh (special font) and Time Zone. 127 | 128 | The **Format Control** section explains how tokens can be used to display various date time elements, plus other special features in S14Clock, builtin features are in the format of tilde + code (ex. ~W), strtime() tokens in the format of percent + code (ex. %H), strtime() is a C language function for date time formatting. 129 | 130 | Change of **Time Zone**, after clicking on the 'Save' button, will also require a hardware reset on the clock unit to take effect. This is a failsafe setup, as 131 | the **Posix TZ** setting should already cover the GMT offset and provide daylight saving time information. 132 | 133 | 134 | ### Startup Options 135 | 136 | 137 | 138 | Upon startup or hardware reset, the clock unit will show briefly various messages, pressing button 0 (of the S2 Mini board) at various stages will allow for certain operations. 139 | 140 | Upon power-up, display will show "000000000000..." for 0.7 seconds, followed by "************..." for 0.4 seconds, it will then show the firmware and hardware versions for 2 seconds. 141 | 142 | 143 | 144 | During the show of "000000000000...", press and hold button 0 will **reset the WIFI credentials** of the clock unit, and upon next reset the clock unit will be placed in strict setup mode only, and will not search for WIFI network setup previously. 145 | 146 | 147 | 148 | During the show of versions, "FWx.xx HWxxx", press button 0 will force the clock unit to enter a **burn-in** mode, and the clock unit will operate the display mechanism without WIFI and NTP connection. 149 | 150 | 151 | ### Firmware Update 152 | 153 | Potential bug fixes and feature enhancements will be provided in [my github repository](https://github.com/simpleavr/s14clock). 154 | 155 | You need a modern / recent browser that supports Web-Serial-API to use the [Firmware Installer](./install.html). 156 | 157 | ### Components and Assembly 158 | 159 | IMG 160 | 161 | 162 | 163 | - 1× ESP32 S2 Mini module, w/ male headers 164 | - ~~1x 74HC154D 4-16 line decoder (not needed for S14-12)~~ 165 | - 4x 3692AS common cathode 14 segments 6 digits LED module (2x for S14-12) 166 | - 2x 8x2 female header 167 | - 4x M3 16mm steel screws 168 | - 4x M3 steel nuts 169 | - 4x M3 8mm black acrylic spacers 170 | - 1x laser cut acrylic filter / front panel 171 | 172 | 173 | 174 | Component placement follows printed circuit board footprints. As all components are symmetrical, please observe orientation when placing. Apart from that the soldering process is straightforward. 175 | 176 | 177 | 178 | ### Schematic and Source Code 179 | 180 | ``` 181 | (S14-24V3 Clock) **latest design, replaces S14-24, eleminates 74HC154** 182 | ESP32 S2 MINI 183 | ----------------- 2x 3692AS LED Displays 184 | | | _____________________________________ 185 | | row 0 |---------------->|D1 ___ ___ | 186 | | row 1 |---------------->|D2 |\|/| _________________ |\|/| | 187 | | row 2 |---------------->|D3 - - ___________________ - - | 188 | | row 3 |---------------->|D4 |/|\| |/|\| | 189 | | row 4 |---------------->|D5 --- --- | 190 | | row 5 |---------------->|D6 A B C D E F 1 2 H J K L M N dp | 191 | | | ----|-|-|-|-|-|-|-|-|-|-|-|-|-|-|---- 192 | | | ____|_|_|_|_|_|_|_|_|_|_|_|_|_|_|____ 193 | | row 6 |---------------->|D1 ___ a | 194 | | row 7 |---------------->|D2 f|\|/|b (hjk) | 195 | | row 8 |---------------->|D3 - - g G | 196 | | row 9 |---------------->|D4 e|/|\|c (nml) | 197 | | row 10|---------------->|D5 === d | 198 | | row 11|---------------->|D6 | 199 | | | ----|-|-|-|-|-|-|-|-|-|-|-|-|-|-|---- 200 | | | | | | | | 201 | | com 0 |----------------------+ | | | NC 202 | | com 1 |------------------------+ | /................/ | 203 | | com 2 |--------------------------+ | 204 | | . ..| .... similar to all common lines ..../ | 205 | | . ..| .... | 206 | | com 13|------------------------------------------------+ 207 | | | **digits become segments, and segments become digits in this charliplexing configuration** 208 | | | 2x 3692AS LED Displays 209 | | | _____________________________________ 210 | | com 0 |---------------->|D1 ___ ___ | 211 | | com 1 |---------------->|D2 |\|/| _________________ |\|/| | 212 | | com 2 |---------------->|D3 - - ___________________ - - | 213 | | com 3 |---------------->|D4 |/|\| |/|\| | 214 | | com 4 |---------------->|D5 --- --- | 215 | | com 5 |---------------->|D6 A B C D E F 1 2 H J K L M N dp | 216 | | | ----|-|-|-|-|-|-|-|-|-|-|-|-|-|-|---- 217 | | | ____|_|_|_|_|_|_|_|_|_|_|_|_|_|_|____ 218 | | com 6 |---------------->|D1 ___ a | 219 | | com 7 |---------------->|D2 f|\|/|b (hjk) | 220 | | com 8 |---------------->|D3 - - g G | 221 | | com 9 |---------------->|D4 e|/|\|c (nml) | 222 | | com 10|---------------->|D5 === d | 223 | | com 11|---------------->|D6 | 224 | | | ----|-|-|-|-|-|-|-|-|-|-|-|-|-|-|---- 225 | | | | | | | | | | | 226 | | row 0 |----------------------+ | | | | | | NC 227 | | row 1 |------------------------+ | /............/ | | | 228 | | row 2 |--------------------------+ | | | 229 | | . ..| .... similar to all row lines ..../ | | | 230 | | row 11|--------------------------------------------+ | | 231 | | com 12|----------------------------------------------+ | 232 | | com 13|------------------------------------------------+ 233 | | | 234 | +-----------------+ * actual io pin to row / col map depends on PCB version 235 | 236 | (S14-12 Clock) 237 | ESP32 S2 MINI 238 | ----------------- 2x 3692AS LED Displays 239 | | | _____________________________________ 240 | | row 0 |---------------->|D1 ___ ___ | 241 | | row 1 |---------------->|D2 |\|/| _________________ |\|/| | 242 | | row 2 |---------------->|D3 - - ___________________ - - | 243 | | row 3 |---------------->|D4 |/|\| |/|\| | 244 | | row 4 |---------------->|D5 --- --- | 245 | | row 5 |---------------->|D6 A B C D E F 1 2 H J K L M N dp | 246 | | | ----|-|-|-|-|-|-|-|-|-|-|-|-|-|-|---- 247 | | | ____|_|_|_|_|_|_|_|_|_|_|_|_|_|_|____ 248 | | row 6 |---------------->|D1 ___ a | 249 | | row 7 |---------------->|D2 f|\|/|b (hjk) | 250 | | row 8 |---------------->|D3 - - g G | 251 | | row 9 |---------------->|D4 e|/|\|c (nml) | 252 | | row 10|---------------->|D5 === d | 253 | | row 11|---------------->|D6 | 254 | | | ----|-|-|-|-|-|-|-|-|-|-|-|-|-|-|---- 255 | | | | | | | | 256 | | com 0 |----------------------+ | | | | 257 | | com 1 |------------------------+ | /................/ | | 258 | | com 2 |--------------------------+ | | 259 | | . ..| .... similar to all common lines ..../ | | 260 | | . ..| .... | | 261 | | com 13|------------------------------------------------+ | 262 | | com 14|--------------------------------------------------+ 263 | | | 264 | +-----------------+ * actual io pin to row / col map depends on PCB version 265 | 266 | 267 | (S14-24 Clock) **obsolete, replaced by S14-24V3** 268 | ESP32 S2 MINI 269 | ----------------- 4x 3692AS LED Displays 270 | | | _____________________________________ 271 | | row 0 |---------------->|D1 ___ ___ | 272 | | row 1 |---------------->|D2 |\|/| _________________ |\|/| | 273 | | row 2 |---------------->|D3 - - ___________________ - - | 274 | | row 3 |---------------->|D4 |/|\| |/|\| | 275 | | row 4 |---------------->|D5 --- --- | 276 | | row 5 |---------------->|D6 A B C D E F 1 2 H J K L M N dp | 277 | | | ----|-|-|-|-|-|-|-|-|-|-|-|-|-|-|---- 278 | | | ____|_|_|_|_|_|_|_|_|_|_|_|_|_|_|____ 279 | | row 6 |---------------->|D1 | 280 | | row 7 |---------------->|D2 | 281 | | | +--- Y0|---->|D3 | 282 | | | | Y1|---->|D4 | 283 | | | | Y2|---->|D5 | 284 | | 3.3V |----|VCC Y3|---->|D6 | 285 | | __ | | | ----|-|-|-|-|-|-|-|-|-|-|-|-|-|-|---- 286 | | EN |--->|EN0 | ____|_|_|_|_|_|_|_|_|_|_|_|_|_|_|____ 287 | | | | Y4|---->|D1 | 288 | | address 0 |--->| Y5|---->|D2 | 289 | | address 1 |--->| Y6|---->|D3 | 290 | | address 2 |--->| Y7|---->|D4 | 291 | | address 3 |--->| Y8|---->|D5 | 292 | | | | Y9|---->|D6 | 293 | | | +--|EN1 | ----|-|-|-|-|-|-|-|-|-|-|-|-|-|-|---- 294 | | GND |-+--|GND | ____|_|_|_|_|_|_|_|_|_|_|_|_|_|_|____ 295 | | | | Y10|---->|D1 | 296 | | | | Y11|---->|D2 | 297 | | | | Y12|---->|D3 | 298 | | | | Y13|---->|D4 | 299 | | | | Y14|---->|D5 | 300 | | | | Y15|---->|D6 | 301 | | | +------+ ----|-|-|-|-|-|-|-|-|-|-|-|-|-|-|---- 302 | | | 74HC154D | | | | | 303 | | | | | | | N.C 304 | | com 0 |----------------------+ | | | 305 | | com 1 |------------------------+ | /................/ | 306 | | com 2 |--------------------------+ | 307 | | . ..| .... similar to all common lines ..../ | 308 | | . ..| .... | 309 | | com 13|------------------------------------------------+ 310 | | | 311 | +-----------------+ * actual io pin to row / col map depends on PCB version 312 | 313 | ``` 314 | The io pin mappings between ESP32 and the led modules are not shown in the schematic. They can be found in the source file. As there are different version of design, the source code is made so that the mapping can be re-defined easily via #define statements. Please consult source code for details. 315 | 316 | This is an open source project. Source code and build instructions can be found in [my github repository](https://github.com/simpleavr/s14clock) 317 | 318 | 319 | 320 | -------------------------------------------------------------------------------- /install.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | S14Clock firmware installer 6 | 10 | 11 | 12 | 57 | 58 | 59 | 60 |
61 |

S14Clock Firmware Installer

62 |
63 |

Instructions

64 |
    65 |
  • Connect clock via usb-c to computer.
  • 66 |
  • Select formware and hit the blue "Connect" button below, a pop-up window will appear.
  • 67 |
  • On the clock side, press and hold '0', then press 'RST', release 'RST', and finally release '0'.
  • 68 |
  • You should see an "ESP32-S2 (COM?)" entry in the pop-up window, if not, release last step.
  • 69 |
  • Select "ESP32-S2 (COM?)" entry and then hit the greem "Connect" button.
  • 70 |
  • Select the "Install ....Firmware..." option, confirm by clicking "Install".
  • 71 |
  • Popup shows progress on Prepare Installation, Erasing, Installing,.., this takes 3 or 4 minutes in total.
  • 72 |
  • Reset clock after flashing and continue with initial setup.
  • 73 |
74 |

See the S14Clock Project.

75 |

Select your product

76 |
    77 |
  • 78 |
  • 79 |
  • 80 |
  • 81 |
  • 82 |
83 |

84 | 85 |

86 |
87 |
88 |
    89 |
  • ensure you use a good data cable
  • 90 |
  • connect via usb-c to usb-c if possible
  • 91 |
  • you will need to enter wifi credential again after upgrade
  • 92 |
  • if this page installer fails to work properly, try manual install via the AdaFruit Web Tool
  • 93 |
94 | Installer powered by ESP Web Tools. 95 |
96 | 97 |
98 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | src_dir = s14clock_firmware 13 | 14 | [env:lolin_s2_mini] 15 | platform = espressif32 16 | board = lolin_s2_mini 17 | #board_build.partitions = min_spiffs.csv 18 | framework = arduino 19 | lib_deps = hieromon/AutoConnect@^1.4.2 20 | -------------------------------------------------------------------------------- /s14clock_firmware/map.h: -------------------------------------------------------------------------------- 1 | const uint8_t digit_map_v2[] = { 10, 12, 13, 14, 16, 8, 11, 35, 38, 37, 40, 39, }; 2 | const uint8_t digit_map_r_v2[] = { 39, 40, 37, 38, 35, 11, 8, 16, 14, 13, 12, 10, }; 3 | 4 | const uint32_t segment_mask_v2 = 0x0b2682fe; 5 | const uint32_t all_mask_v2 = 0xff27fffe; 6 | const uint32_t spin_mask_v2[] = { 7 | 0x00020000, 0x00220000, 0x00220002, 0x0022000a, 8 | 0x0022000e, 0x0026000e, 0x0026002e, 0x0026003e, 9 | 0x0226003e, 0x0326003e, 0x0b26003e, 0x0b2600be, 10 | 0x0b2600fe, 0x0b2602fe, 0x0b2682fe, }; 11 | const uint32_t asciiA_v2[] = { 12 | 0x0000003e, 0x00000030, 0x00000038, 0x00020038, 0x0a260030, 0x0102007a, 0x010002b0, 0x01000238, 13 | 0x00000280, 0x01000232, 0x00000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 14 | 0x00260030, 0x01000040, 0x01200042, 0x01240046, 0x0a000280, 0x0202021a, 0x01000030, 0x01000038, 15 | 0x01020038, 0x0a020280, 0x00000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 16 | 0x00000000, 0x00200002, 0x01200000, 0x0120007a, 0x0106007a, 0x0b0402f2, 0x030200ac, 0x01000000, 17 | 0x08000080, 0x02000200, 0x0b0002f0, 0x01000070, 0x00000200, 0x00000030, 0x00000040, 0x08000200, 18 | 0x0826020e, 0x08200002, 0x0022003c, 0x0022001a, 0x00240032, 0x000600a8, 0x0006003e, 0x00220002, 19 | 0x0026003e, 0x0026003a, 0x00000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 20 | 0x0126001c, 0x00260036, 0x0122005a, 0x0006000c, 0x0122004a, 0x0006002c, 0x00060024, 0x0006001e, 21 | 0x00240036, 0x01020048, 0x0020000e, 0x080400a4, 0x0004000c, 0x0a240006, 0x02240086, 0x0026000e, 22 | 0x00260034, 0x0026008e, 0x002600b4, 0x0006003a, 0x01020040, 0x0024000e, 0x08040204, 0x00240286, 23 | 0x0a000280, 0x0024003a, 0x08020208, 0x0006000c, 0x02000080, 0x0022000a, 0x00000280, 0x00000008, 24 | 0x02000000, 0x0000006c, 0x000400ac, 0x0000003c, 0x0020021a, 0x0000022c, 0x08000070, 0x0820001a, 25 | 0x00040064, 0x00000040, 0x01000204, 0x090000c0, 0x00040004, 0x00000076, 0x00000064, 0x0000003e, 26 | 0x02040024, 0x08200012, 0x00000024, 0x00000098, 0x0004002c, 0x0000000e, 0x00000204, 0x00000286, 27 | 0x0a000280, 0x0120001a, 0x00000228, 0x02020228, 0x01000040, 0x08020098, 0x08000230, 0x00000000, 28 | 0x0000003e, 0x00000030, 0x00000038, 0x00020038, 0x0a260030, 0x0102007a, 0x010002b0, 0x08000238, 29 | 0x00000280, 0x01000232, 0x00000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 30 | 0x0000003e, 0x00000030, 0x000000a6, 0x00000076, 0x01020020, 0x08240020, 0x0000005a, 0x00060000, 31 | 0x01260030, 0x01060020, 0x00000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 32 | 0x00000000, 0x00200002, 0x01200000, 0x0120007a, 0x0106007a, 0x0b0402f2, 0x030200ac, 0x01000000, 33 | 0x08000080, 0x02000200, 0x0b0002f0, 0x01000070, 0x00000200, 0x00000030, 0x00000040, 0x08000200, 34 | 0x0026002e, 0x01000048, 0x00220038, 0x0022002a, 0x00240032, 0x0002003a, 0x0002003e, 0x00220002, 35 | 0x0026003e, 0x00260038, 0x01000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 36 | 0x0126001c, 0x080400a4, 0x0006001c, 0x01240002, 0x08020220, 0x08240216, 0x0900006c, 0x08060020, 37 | 0x00020028, 0x08200002, 0x0820002a, 0x00220030, 0x00200082, 0x00000218, 0x00000284, 0x00000298, 38 | 0x0000002e, 0x0026000c, 0x08020200, 0x0220008a, 0x0b000000, 0x0824000e, 0x0a000040, 0x00260030, 39 | 0x00000288, 0x03000082, 0x0000021a, 0x0006000c, 0x02000080, 0x0022000a, 0x00000280, 0x00000008, 40 | 0x02000000, 0x080400a4, 0x0006001c, 0x01240002, 0x08020220, 0x08240216, 0x0900006c, 0x08060020, 41 | 0x00020028, 0x08200002, 0x0820002a, 0x00220030, 0x00200082, 0x00000218, 0x00000284, 0x00000298, 42 | 0x0000002e, 0x0026000c, 0x08020200, 0x0220008a, 0x0b000000, 0x0824000e, 0x0a000040, 0x00260030, 43 | 0x00000288, 0x03000082, 0x0000021a, 0x02020228, 0x01000040, 0x08020098, 0x08000230, 0x00000000, 44 | }; 45 | 46 | const uint32_t asciiB_v2[] = { 47 | 0x00260030, 0x00000030, 0x00020030, 0x00020038, 0x000002be, 0x01060078, 0x0a000070, 0x08020070, 48 | 0x0a000000, 0x08040070, 0x01000000, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 49 | 0x0000003e, 0x01000040, 0x01040044, 0x01240046, 0x0a000280, 0x080600a8, 0x00000070, 0x00020070, 50 | 0x00020078, 0x0a000288, 0x01000000, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 51 | 0x00000000, 0x00040004, 0x00000044, 0x01060074, 0x0106007a, 0x0b0402f2, 0x022200d8, 0x00000040, 52 | 0x02000200, 0x08000080, 0x0b0002f0, 0x01000070, 0x08000000, 0x00000030, 0x01000000, 0x08000200, 53 | 0x0826020e, 0x00040204, 0x0022003c, 0x0006002c, 0x00040036, 0x0202001a, 0x0026003a, 0x0004000c, 54 | 0x0026003e, 0x0006003e, 0x01000000, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 55 | 0x0022006e, 0x0024003e, 0x0106006c, 0x0022000a, 0x0106004c, 0x0022001a, 0x0020001a, 0x0026002a, 56 | 0x00240036, 0x01020048, 0x00260004, 0x02200212, 0x00220002, 0x00240286, 0x02240086, 0x0026000e, 57 | 0x0020003e, 0x0226000e, 0x0220003e, 0x0006003a, 0x01000048, 0x00260006, 0x08200202, 0x0a240006, 58 | 0x0a000280, 0x00060036, 0x08020208, 0x0022000a, 0x02000080, 0x0006000c, 0x0a000000, 0x00020000, 59 | 0x00000080, 0x01220010, 0x02220012, 0x00220030, 0x08060024, 0x08220010, 0x01000230, 0x00060224, 60 | 0x01200012, 0x01000000, 0x08200040, 0x03000240, 0x00200002, 0x01240030, 0x01200010, 0x00260030, 61 | 0x00200092, 0x00040224, 0x00200010, 0x02020020, 0x00220012, 0x00260000, 0x08200000, 0x0a240000, 62 | 0x0a000280, 0x00060064, 0x08020010, 0x08020098, 0x01000040, 0x02020228, 0x08000230, 0x00000000, 63 | 0x00260030, 0x00000030, 0x00020030, 0x00020038, 0x000002be, 0x01060078, 0x0a000070, 0x08020230, 64 | 0x0a000000, 0x08040070, 0x01000000, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 65 | 0x00260030, 0x00000030, 0x02240010, 0x01240030, 0x00000058, 0x00000216, 0x01060020, 0x0000000a, 66 | 0x0000007e, 0x0000005a, 0x01000000, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 67 | 0x00000000, 0x00040004, 0x00000044, 0x01060074, 0x0106007a, 0x0b0402f2, 0x022200d8, 0x00000040, 68 | 0x02000200, 0x08000080, 0x0b0002f0, 0x01000070, 0x08000000, 0x00000030, 0x01000000, 0x08000200, 69 | 0x0026001e, 0x01020040, 0x0002003c, 0x0006001c, 0x00040036, 0x00060038, 0x00260038, 0x0004000c, 70 | 0x0026003e, 0x0002003e, 0x01000040, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 71 | 0x0022006e, 0x02200212, 0x0022002a, 0x00040046, 0x08000218, 0x08240226, 0x01220250, 0x0000021a, 72 | 0x00020018, 0x00040204, 0x00060214, 0x0000003c, 0x02040004, 0x08020020, 0x0a200000, 0x0a020020, 73 | 0x00260010, 0x0022000e, 0x08000208, 0x02060084, 0x000002c0, 0x00260206, 0x01000280, 0x0000003e, 74 | 0x0a020000, 0x020400c0, 0x08060020, 0x0022000a, 0x02000080, 0x0006000c, 0x0a000000, 0x00020000, 75 | 0x00000080, 0x02200212, 0x0022002a, 0x00040046, 0x08000218, 0x08240226, 0x01220250, 0x0000021a, 76 | 0x00020018, 0x00040204, 0x00060214, 0x0000003c, 0x02040004, 0x08020020, 0x0a200000, 0x0a020020, 77 | 0x00260010, 0x0022000e, 0x08000208, 0x02060084, 0x000002c0, 0x00260206, 0x01000280, 0x0000003e, 78 | 0x0a020000, 0x020400c0, 0x08060020, 0x08020098, 0x01000040, 0x02020228, 0x08000230, 0x00000000, 79 | }; 80 | 81 | const uint8_t asciiOnOff[] = { 82 | 0x05, 0x02, 0x03, 0x04, 0x07, 0x07, 0x05, 0x05, 83 | 0x02, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 84 | 0x05, 0x02, 0x04, 0x06, 0x04, 0x06, 0x03, 0x04, 85 | 0x05, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 86 | 0x00, 0x02, 0x02, 0x07, 0x08, 0x0a, 0x07, 0x01, 87 | 0x02, 0x02, 0x08, 0x04, 0x01, 0x02, 0x01, 0x02, 88 | 0x08, 0x03, 0x06, 0x05, 0x05, 0x05, 0x07, 0x03, 89 | 0x08, 0x07, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 90 | 0x07, 0x07, 0x07, 0x04, 0x06, 0x05, 0x04, 0x06, 91 | 0x06, 0x04, 0x04, 0x05, 0x03, 0x06, 0x06, 0x06, 92 | 0x06, 0x07, 0x07, 0x06, 0x03, 0x05, 0x04, 0x06, 93 | 0x04, 0x06, 0x04, 0x04, 0x02, 0x04, 0x02, 0x01, 94 | 0x01, 0x04, 0x05, 0x04, 0x05, 0x04, 0x04, 0x05, 95 | 0x04, 0x01, 0x03, 0x04, 0x02, 0x05, 0x03, 0x05, 96 | 0x04, 0x04, 0x02, 0x03, 0x04, 0x03, 0x02, 0x04, 97 | 0x04, 0x05, 0x03, 0x05, 0x02, 0x05, 0x04, 0x00, 98 | 0x05, 0x02, 0x03, 0x04, 0x07, 0x07, 0x05, 0x05, 99 | 0x02, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 100 | 0x05, 0x02, 0x04, 0x05, 0x03, 0x04, 0x04, 0x02, 101 | 0x06, 0x04, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 102 | 0x00, 0x02, 0x02, 0x07, 0x08, 0x0a, 0x07, 0x01, 103 | 0x02, 0x02, 0x08, 0x04, 0x01, 0x02, 0x01, 0x02, 104 | 0x07, 0x03, 0x05, 0x05, 0x05, 0x05, 0x06, 0x03, 105 | 0x08, 0x06, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 106 | 0x07, 0x05, 0x05, 0x04, 0x04, 0x07, 0x06, 0x04, 107 | 0x03, 0x03, 0x05, 0x04, 0x03, 0x03, 0x03, 0x04, 108 | 0x04, 0x05, 0x03, 0x05, 0x03, 0x06, 0x03, 0x05, 109 | 0x03, 0x04, 0x04, 0x04, 0x02, 0x04, 0x02, 0x01, 110 | 0x01, 0x05, 0x05, 0x04, 0x04, 0x07, 0x06, 0x04, 111 | 0x03, 0x03, 0x05, 0x04, 0x03, 0x03, 0x03, 0x04, 112 | 0x04, 0x05, 0x03, 0x05, 0x03, 0x06, 0x03, 0x05, 113 | 0x03, 0x04, 0x04, 0x05, 0x02, 0x05, 0x04, 0x00, 114 | }; 115 | 116 | const uint8_t digit_map_v2l[] = { 34, 16, 17, 18, 21, 33, 36, 35, 37, 38, 39, 40, }; 117 | const uint8_t digit_map_r_v2l[] = { 40, 39, 38, 37, 35, 36, 33, 21, 18, 17, 16, 34, }; 118 | 119 | const uint32_t segment_mask_v2l = 0x00007ffe; 120 | const uint32_t all_mask_v2l = 0xff277ffe; 121 | const uint32_t spin_mask_v2l[] = { 122 | 0x00000800, 0x00002800, 0x00002802, 0x00002822, 123 | 0x00002826, 0x00006826, 0x0000682e, 0x0000683e, 124 | 0x0000693e, 0x00006b3e, 0x00006f3e, 0x00006fbe, 125 | 0x00006ffe, 0x00007ffe, 0x00007ffe, }; 126 | const uint32_t asciiA_v2l[] = { 127 | 0x0000003e, 0x00000018, 0x00000038, 0x00000838, 0x00006d18, 0x00000a7a, 0x00001298, 0x00001238, 128 | 0x00001080, 0x0000121a, 0x00000040, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 129 | 0x00006818, 0x00000240, 0x00002242, 0x00006246, 0x00001580, 0x00001932, 0x00000218, 0x00000238, 130 | 0x00000a38, 0x00001d80, 0x00000040, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 131 | 0x00000000, 0x00002002, 0x00002200, 0x0000227a, 0x00004a7a, 0x000057da, 0x00000bac, 0x00000200, 132 | 0x00000480, 0x00001100, 0x000017d8, 0x00000258, 0x00001000, 0x00000018, 0x00000040, 0x00001400, 133 | 0x00007c26, 0x00002402, 0x0000283c, 0x00002832, 0x0000601a, 0x000048a8, 0x0000483e, 0x00002802, 134 | 0x0000683e, 0x0000683a, 0x00000040, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 135 | 0x00006a34, 0x0000681e, 0x00002a72, 0x00004824, 0x00002a62, 0x0000482c, 0x0000480c, 0x00004836, 136 | 0x0000601e, 0x00000a60, 0x00002026, 0x0000448c, 0x00004024, 0x00006506, 0x00006186, 0x00006826, 137 | 0x0000681c, 0x000068a6, 0x0000689c, 0x0000483a, 0x00000a40, 0x00006026, 0x00005404, 0x00007086, 138 | 0x00001580, 0x0000603a, 0x00001c20, 0x00004824, 0x00000180, 0x00002822, 0x00001080, 0x00000020, 139 | 0x00000100, 0x0000006c, 0x000040ac, 0x0000003c, 0x00003032, 0x0000102c, 0x00000458, 0x00002432, 140 | 0x0000404c, 0x00000040, 0x00001204, 0x000006c0, 0x00004004, 0x0000005e, 0x0000004c, 0x0000003e, 141 | 0x0000410c, 0x00002412, 0x0000000c, 0x000000b0, 0x0000402c, 0x00000026, 0x00001004, 0x00001086, 142 | 0x00001580, 0x00002232, 0x00001028, 0x00001928, 0x00000240, 0x00000cb0, 0x00001418, 0x00000000, 143 | 0x0000003e, 0x00000018, 0x00000038, 0x00000838, 0x00006d18, 0x00000a7a, 0x00001298, 0x00001438, 144 | 0x00001080, 0x0000121a, 0x00000040, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 145 | 0x0000003e, 0x00000018, 0x0000008e, 0x0000005e, 0x00000a08, 0x00006408, 0x00000072, 0x00004800, 146 | 0x00006a18, 0x00004a08, 0x00000040, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 147 | 0x00000000, 0x00002002, 0x00002200, 0x0000227a, 0x00004a7a, 0x000057da, 0x00000bac, 0x00000200, 148 | 0x00000480, 0x00001100, 0x000017d8, 0x00000258, 0x00001000, 0x00000018, 0x00000040, 0x00001400, 149 | 0x0000682e, 0x00000260, 0x00002838, 0x0000282a, 0x0000601a, 0x0000083a, 0x0000083e, 0x00002802, 150 | 0x0000683e, 0x00006838, 0x00000240, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 151 | 0x00006a34, 0x0000448c, 0x00004834, 0x00006202, 0x00001c08, 0x00007416, 0x0000066c, 0x00004c08, 152 | 0x00000828, 0x00002402, 0x0000242a, 0x00002818, 0x00002082, 0x00001030, 0x00001084, 0x000010b0, 153 | 0x0000002e, 0x00006824, 0x00001c00, 0x000021a2, 0x00000700, 0x00006426, 0x00000540, 0x00006818, 154 | 0x000010a0, 0x00000382, 0x00001032, 0x00004824, 0x00000180, 0x00002822, 0x00001080, 0x00000020, 155 | 0x00000100, 0x0000448c, 0x00004834, 0x00006202, 0x00001c08, 0x00007416, 0x0000066c, 0x00004c08, 156 | 0x00000828, 0x00002402, 0x0000242a, 0x00002818, 0x00002082, 0x00001030, 0x00001084, 0x000010b0, 157 | 0x0000002e, 0x00006824, 0x00001c00, 0x000021a2, 0x00000700, 0x00006426, 0x00000540, 0x00006818, 158 | 0x000010a0, 0x00000382, 0x00001032, 0x00001928, 0x00000240, 0x00000cb0, 0x00001418, 0x00000000, 159 | }; 160 | 161 | const uint32_t asciiB_v2l[] = { 162 | 0x00006818, 0x00000018, 0x00000818, 0x00000838, 0x000010be, 0x00004a78, 0x00000558, 0x00000c58, 163 | 0x00000500, 0x00004458, 0x00000200, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 164 | 0x0000003e, 0x00000240, 0x00004244, 0x00006246, 0x00001580, 0x00004ca8, 0x00000058, 0x00000858, 165 | 0x00000878, 0x000015a0, 0x00000200, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 166 | 0x00000000, 0x00004004, 0x00000044, 0x00004a5c, 0x00004a7a, 0x000057da, 0x000029f0, 0x00000040, 167 | 0x00001100, 0x00000480, 0x000017d8, 0x00000258, 0x00000400, 0x00000018, 0x00000200, 0x00001400, 168 | 0x00007c26, 0x00005004, 0x0000283c, 0x0000482c, 0x0000401e, 0x00000932, 0x0000683a, 0x00004024, 169 | 0x0000683e, 0x0000483e, 0x00000200, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 170 | 0x0000286e, 0x0000603e, 0x00004a6c, 0x00002822, 0x00004a64, 0x00002832, 0x00002032, 0x0000682a, 171 | 0x0000601e, 0x00000a60, 0x00006804, 0x00003112, 0x00002802, 0x00007086, 0x00006186, 0x00006826, 172 | 0x0000203e, 0x00006926, 0x0000213e, 0x0000483a, 0x00000260, 0x00006806, 0x00003402, 0x00006506, 173 | 0x00001580, 0x0000481e, 0x00001c20, 0x00002822, 0x00000180, 0x00004824, 0x00000500, 0x00000800, 174 | 0x00000080, 0x00002a10, 0x00002912, 0x00002818, 0x00004c0c, 0x00002c10, 0x00001218, 0x0000580c, 175 | 0x00002212, 0x00000200, 0x00002440, 0x00001340, 0x00002002, 0x00006218, 0x00002210, 0x00006818, 176 | 0x00002092, 0x0000500c, 0x00002010, 0x00000908, 0x00002812, 0x00006800, 0x00002400, 0x00006500, 177 | 0x00001580, 0x0000484c, 0x00000c10, 0x00000cb0, 0x00000240, 0x00001928, 0x00001418, 0x00000000, 178 | 0x00006818, 0x00000018, 0x00000818, 0x00000838, 0x000010be, 0x00004a78, 0x00000558, 0x00001c18, 179 | 0x00000500, 0x00004458, 0x00000200, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 180 | 0x00006818, 0x00000018, 0x00006110, 0x00006218, 0x00000070, 0x00001016, 0x00004a08, 0x00000022, 181 | 0x0000007e, 0x00000072, 0x00000200, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 182 | 0x00000000, 0x00004004, 0x00000044, 0x00004a5c, 0x00004a7a, 0x000057da, 0x000029f0, 0x00000040, 183 | 0x00001100, 0x00000480, 0x000017d8, 0x00000258, 0x00000400, 0x00000018, 0x00000200, 0x00001400, 184 | 0x00006836, 0x00000a40, 0x0000083c, 0x00004834, 0x0000401e, 0x00004838, 0x00006838, 0x00004024, 185 | 0x0000683e, 0x0000083e, 0x00000240, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 186 | 0x0000286e, 0x00003112, 0x0000282a, 0x00004046, 0x00001430, 0x0000740e, 0x00003a50, 0x00001032, 187 | 0x00000830, 0x00005004, 0x00005814, 0x0000003c, 0x00004104, 0x00000c08, 0x00002500, 0x00000d08, 188 | 0x00006810, 0x00002826, 0x00001420, 0x00004984, 0x000010c0, 0x00007806, 0x00001280, 0x0000003e, 189 | 0x00000d00, 0x000041c0, 0x00004c08, 0x00002822, 0x00000180, 0x00004824, 0x00000500, 0x00000800, 190 | 0x00000080, 0x00003112, 0x0000282a, 0x00004046, 0x00001430, 0x0000740e, 0x00003a50, 0x00001032, 191 | 0x00000830, 0x00005004, 0x00005814, 0x0000003c, 0x00004104, 0x00000c08, 0x00002500, 0x00000d08, 192 | 0x00006810, 0x00002826, 0x00001420, 0x00004984, 0x000010c0, 0x00007806, 0x00001280, 0x0000003e, 193 | 0x00000d00, 0x000041c0, 0x00004c08, 0x00000cb0, 0x00000240, 0x00001928, 0x00001418, 0x00000000, 194 | }; 195 | 196 | const uint8_t digit_map_v3[] = { 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 5, 33, 3, 7, 8, 14, 36, 13, 12, 39, 38, 15, 2, }; 197 | const uint8_t digit_map_r_v3[] = { 2, 15, 38, 39, 12, 13, 36, 14, 8, 7, 3, 33, 5, 37, 40, 10, 4, 1, 17, 16, 21, 34, 35, 6, }; 198 | 199 | const uint32_t segment_mask_v3 = 0x6900fb8c; 200 | const uint32_t all_mask_v3 = 0xff23fffe; 201 | const uint32_t spin_mask_v3[] = { 202 | 0x01000000, 0x01000008, 0x01000088, 0x01000188, 203 | 0x01004188, 0x09004188, 0x09006188, 0x09007188, 204 | 0x49007188, 0x69007188, 0x6900f188, 0x6900f18c, 205 | 0x6900f98c, 0x6900fb8c, 0x6900fb8c, }; 206 | const uint32_t asciiA_v3[] = { 207 | 0x00007180, 0x00003000, 0x00003100, 0x01003100, 0x4900b008, 0x21003980, 0x20003204, 0x20003300, 208 | 0x00000204, 0x20003280, 0x00000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01001808, 209 | 0x09003008, 0x20000800, 0x20000888, 0x28004888, 0x40008204, 0x41001380, 0x20003000, 0x20003100, 210 | 0x21003100, 0x41008204, 0x00000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01001808, 211 | 0x00000000, 0x00000088, 0x20000008, 0x20003988, 0x29003980, 0x6800ba84, 0x61006104, 0x20000000, 212 | 0x00008004, 0x40000200, 0x6000ba04, 0x20003800, 0x00000200, 0x00003000, 0x00000800, 0x00008200, 213 | 0x0900c388, 0x00008088, 0x01007108, 0x01001188, 0x08003088, 0x09002104, 0x09007180, 0x01000088, 214 | 0x09007188, 0x09003188, 0x00000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01001808, 215 | 0x29005108, 0x09007088, 0x21001988, 0x09004100, 0x21000988, 0x09006100, 0x09006000, 0x09005180, 216 | 0x08007088, 0x21000900, 0x00004188, 0x0800e004, 0x08004100, 0x4800c088, 0x4800408c, 0x09004188, 217 | 0x09007008, 0x0900418c, 0x0900700c, 0x09003180, 0x21000800, 0x08004188, 0x0800c200, 0x0800428c, 218 | 0x40008204, 0x08003188, 0x01008300, 0x09004100, 0x40000004, 0x01000188, 0x00000204, 0x00000100, 219 | 0x40000000, 0x00006900, 0x08006104, 0x00007100, 0x00001388, 0x00006300, 0x0000b800, 0x00009188, 220 | 0x08006800, 0x00000800, 0x20004200, 0x20008804, 0x08004000, 0x00007880, 0x00006800, 0x00007180, 221 | 0x48006000, 0x00009088, 0x00006000, 0x00001104, 0x08006100, 0x00004180, 0x00004200, 0x00004284, 222 | 0x40008204, 0x20001188, 0x00002300, 0x41002300, 0x20000800, 0x01009104, 0x0000b200, 0x00000000, 223 | 0x00007180, 0x00003000, 0x00003100, 0x01003100, 0x4900b008, 0x21003980, 0x20003204, 0x0000b300, 224 | 0x00000204, 0x20003280, 0x00000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01001808, 225 | 0x00007180, 0x00003000, 0x00006084, 0x00007880, 0x21002000, 0x0800a008, 0x00001980, 0x09000000, 226 | 0x29003008, 0x29002000, 0x00000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01001808, 227 | 0x00000000, 0x00000088, 0x20000008, 0x20003988, 0x29003980, 0x6800ba84, 0x61006104, 0x20000000, 228 | 0x00008004, 0x40000200, 0x6000ba04, 0x20003800, 0x00000200, 0x00003000, 0x00000800, 0x00008200, 229 | 0x09006188, 0x20000900, 0x01003108, 0x01002188, 0x08003088, 0x01003180, 0x01007180, 0x01000088, 230 | 0x09007188, 0x09003108, 0x20000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01001808, 231 | 0x29005108, 0x0800e004, 0x09005100, 0x28000088, 0x0100a200, 0x0800d288, 0x2000e900, 0x0900a000, 232 | 0x01002100, 0x00008088, 0x0000a188, 0x01003008, 0x0000008c, 0x00001300, 0x00004204, 0x00001304, 233 | 0x00006180, 0x09004108, 0x01008200, 0x4000018c, 0x60008000, 0x0800c188, 0x40008800, 0x09003008, 234 | 0x00000304, 0x60000084, 0x00001380, 0x09004100, 0x40000004, 0x01000188, 0x00000204, 0x00000100, 235 | 0x40000000, 0x0800e004, 0x09005100, 0x28000088, 0x0100a200, 0x0800d288, 0x2000e900, 0x0900a000, 236 | 0x01002100, 0x00008088, 0x0000a188, 0x01003008, 0x0000008c, 0x00001300, 0x00004204, 0x00001304, 237 | 0x00006180, 0x09004108, 0x01008200, 0x4000018c, 0x60008000, 0x0800c188, 0x40008800, 0x09003008, 238 | 0x00000304, 0x60000084, 0x00001380, 0x41002300, 0x20000800, 0x01009104, 0x0000b200, 0x00000000, 239 | }; 240 | 241 | const uint32_t asciiB_v3[] = { 242 | 0x09003008, 0x00003000, 0x01003000, 0x01003100, 0x00007384, 0x29003900, 0x4000b800, 0x0100b800, 243 | 0x40008000, 0x0800b800, 0x20000000, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 244 | 0x00007180, 0x20000800, 0x28004800, 0x28004888, 0x40008204, 0x0900a104, 0x00003800, 0x01003800, 245 | 0x01003900, 0x40008304, 0x20000000, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 246 | 0x00000000, 0x08004000, 0x00004800, 0x29007800, 0x29003980, 0x6800ba84, 0x4100190c, 0x00000800, 247 | 0x40000200, 0x00008004, 0x6000ba04, 0x20003800, 0x00008000, 0x00003000, 0x20000000, 0x00008200, 248 | 0x0900c388, 0x08004200, 0x01007108, 0x09006100, 0x08007080, 0x41001180, 0x09003188, 0x08004100, 249 | 0x09007188, 0x09007180, 0x20000000, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 250 | 0x01006988, 0x08007188, 0x29006900, 0x01000188, 0x29004900, 0x01001188, 0x00001188, 0x09002188, 251 | 0x08007088, 0x21000900, 0x09004008, 0x40001288, 0x01000088, 0x0800428c, 0x4800408c, 0x09004188, 252 | 0x00007188, 0x49004188, 0x40007188, 0x09003180, 0x20000900, 0x09004088, 0x00008288, 0x4800c088, 253 | 0x40008204, 0x09007080, 0x01008300, 0x01000188, 0x40000004, 0x09004100, 0x40008000, 0x01000000, 254 | 0x00000004, 0x21001008, 0x41001088, 0x01003008, 0x0900e000, 0x01009008, 0x20003200, 0x09006200, 255 | 0x20001088, 0x20000000, 0x00008808, 0x60000a00, 0x00000088, 0x28003008, 0x20001008, 0x09003008, 256 | 0x0000108c, 0x08006200, 0x00001008, 0x41002000, 0x01001088, 0x09000008, 0x00008008, 0x48008008, 257 | 0x40008204, 0x09006800, 0x01009000, 0x01009104, 0x20000800, 0x41002300, 0x0000b200, 0x00000000, 258 | 0x09003008, 0x00003000, 0x01003000, 0x01003100, 0x00007384, 0x29003900, 0x4000b800, 0x0100b200, 259 | 0x40008000, 0x0800b800, 0x20000000, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 260 | 0x09003008, 0x00003000, 0x48001008, 0x28003008, 0x00001900, 0x00005280, 0x29002000, 0x00000180, 261 | 0x00007980, 0x00001980, 0x20000000, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 262 | 0x00000000, 0x08004000, 0x00004800, 0x29007800, 0x29003980, 0x6800ba84, 0x4100190c, 0x00000800, 263 | 0x40000200, 0x00008004, 0x6000ba04, 0x20003800, 0x00008000, 0x00003000, 0x20000000, 0x00008200, 264 | 0x09005188, 0x21000800, 0x01007100, 0x09005100, 0x08007080, 0x09003100, 0x09003108, 0x08004100, 265 | 0x09007188, 0x01007180, 0x20000800, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 266 | 0x01006988, 0x40001288, 0x01002188, 0x08004880, 0x00009300, 0x0800e288, 0x21001a08, 0x00001380, 267 | 0x01001100, 0x08004200, 0x09005200, 0x00007100, 0x48004000, 0x0100a000, 0x40008008, 0x4100a000, 268 | 0x09001008, 0x01004188, 0x00008300, 0x49004004, 0x00000a04, 0x09004288, 0x20000204, 0x00007180, 269 | 0x41008000, 0x48000804, 0x0900a000, 0x01000188, 0x40000004, 0x09004100, 0x40008000, 0x01000000, 270 | 0x00000004, 0x40001288, 0x01002188, 0x08004880, 0x00009300, 0x0800e288, 0x21001a08, 0x00001380, 271 | 0x01001100, 0x08004200, 0x09005200, 0x00007100, 0x48004000, 0x0100a000, 0x40008008, 0x4100a000, 272 | 0x09001008, 0x01004188, 0x00008300, 0x49004004, 0x00000a04, 0x09004288, 0x20000204, 0x00007180, 273 | 0x41008000, 0x48000804, 0x0900a000, 0x01009104, 0x20000800, 0x41002300, 0x0000b200, 0x00000000, 274 | }; 275 | 276 | const uint32_t segment_mask_v3_c = 0x96230e72; 277 | const uint32_t spin_mask_v3_c[] = { 278 | 0x00000040, 0x04000040, 0x06000040, 0x06200040, 279 | 0x06210040, 0x06230040, 0x06230042, 0x06230052, 280 | 0x06230452, 0x86230452, 0x96230452, 0x96230472, 281 | 0x96230c72, 0x96230e72, 0x96230e72, }; 282 | const uint32_t asciiA_v3_c[] = { 283 | 0x02210012, 0x00000012, 0x00200012, 0x00200052, 0x14020452, 0x82200852, 0x80000232, 0x80200212, 284 | 0x00000220, 0x82000212, 0x00000800, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000850, 285 | 0x04020052, 0x80000800, 0x86000800, 0x86030800, 0x10000620, 0x02200650, 0x80000012, 0x80200012, 286 | 0x80200052, 0x10000660, 0x00000800, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000850, 287 | 0x00000000, 0x06000000, 0x84000000, 0x86200812, 0x82220852, 0x92020e32, 0x80210462, 0x80000000, 288 | 0x10000020, 0x00000600, 0x90000e32, 0x80000812, 0x00000200, 0x00000012, 0x00000800, 0x10000200, 289 | 0x16230240, 0x16000000, 0x04210052, 0x06200050, 0x06020012, 0x00220062, 0x02230052, 0x06000040, 290 | 0x06230052, 0x06220052, 0x00000800, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000850, 291 | 0x84230050, 0x06030052, 0x86200850, 0x00230040, 0x86200840, 0x00230042, 0x00030042, 0x02230050, 292 | 0x06030012, 0x80200840, 0x06210000, 0x10030022, 0x00230000, 0x16030400, 0x06030420, 0x06230040, 293 | 0x04030052, 0x06230060, 0x04030072, 0x02220052, 0x80000840, 0x06230000, 0x10030200, 0x06030220, 294 | 0x10000620, 0x06220012, 0x10200240, 0x00230040, 0x00000420, 0x06200040, 0x00000220, 0x00200000, 295 | 0x00000400, 0x00210802, 0x00230022, 0x00210012, 0x06200210, 0x00210202, 0x10000812, 0x16200010, 296 | 0x00030802, 0x00000800, 0x80010200, 0x90000820, 0x00030000, 0x02010812, 0x00010802, 0x02210012, 297 | 0x00030402, 0x16000010, 0x00010002, 0x00200030, 0x00230002, 0x02210000, 0x00010200, 0x02010220, 298 | 0x10000620, 0x86200010, 0x00200202, 0x00200642, 0x80000800, 0x10200070, 0x10000212, 0x00000000, 299 | 0x02210012, 0x00000012, 0x00200012, 0x00200052, 0x14020452, 0x82200852, 0x80000232, 0x10200212, 300 | 0x00000220, 0x82000212, 0x00000800, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000850, 301 | 0x02210012, 0x00000012, 0x02010022, 0x02010812, 0x80000042, 0x14020002, 0x02200810, 0x00020040, 302 | 0x84020052, 0x80020042, 0x00000800, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000850, 303 | 0x00000000, 0x06000000, 0x84000000, 0x86200812, 0x82220852, 0x92020e32, 0x80210462, 0x80000000, 304 | 0x10000020, 0x00000600, 0x90000e32, 0x80000812, 0x00000200, 0x00000012, 0x00000800, 0x10000200, 305 | 0x06230042, 0x80200800, 0x04200052, 0x06200042, 0x06020012, 0x02200052, 0x02210052, 0x06000040, 306 | 0x06230052, 0x04220052, 0x80000800, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000850, 307 | 0x84230050, 0x10030022, 0x00230050, 0x86020000, 0x10000242, 0x16030210, 0x90210802, 0x10020042, 308 | 0x00200042, 0x16000000, 0x16200002, 0x04000052, 0x06000020, 0x00200210, 0x00010220, 0x00200230, 309 | 0x02210002, 0x04230040, 0x10000240, 0x06200420, 0x90000400, 0x16230000, 0x10000c00, 0x04020052, 310 | 0x00200220, 0x82000420, 0x02200210, 0x00230040, 0x00000420, 0x06200040, 0x00000220, 0x00200000, 311 | 0x00000400, 0x10030022, 0x00230050, 0x86020000, 0x10000242, 0x16030210, 0x90210802, 0x10020042, 312 | 0x00200042, 0x16000000, 0x16200002, 0x04000052, 0x06000020, 0x00200210, 0x00010220, 0x00200230, 313 | 0x02210002, 0x04230040, 0x10000240, 0x06200420, 0x90000400, 0x16230000, 0x10000c00, 0x04020052, 314 | 0x00200220, 0x82000420, 0x02200210, 0x00200642, 0x80000800, 0x10200070, 0x10000212, 0x00000000, 315 | }; 316 | 317 | const uint32_t asciiB_v3_c[] = { 318 | 0x04020052, 0x00000012, 0x00000052, 0x00200052, 0x02210232, 0x80220852, 0x10000c12, 0x10000852, 319 | 0x10000400, 0x10020812, 0x80000000, 0x10000800, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 320 | 0x02210012, 0x80000800, 0x80030800, 0x86030800, 0x10000620, 0x10220062, 0x00000812, 0x00000852, 321 | 0x00200852, 0x10200620, 0x80000000, 0x10000800, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 322 | 0x00000000, 0x00030000, 0x00010800, 0x80030852, 0x82220852, 0x92020e32, 0x04200c70, 0x00000800, 323 | 0x00000600, 0x10000020, 0x90000e32, 0x80000812, 0x10000000, 0x00000012, 0x80000000, 0x10000200, 324 | 0x16230240, 0x00030200, 0x04210052, 0x00230042, 0x02030012, 0x02200450, 0x06220052, 0x00230000, 325 | 0x06230052, 0x02230052, 0x80000000, 0x10000800, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 326 | 0x06210842, 0x06230012, 0x80230842, 0x06200040, 0x80230840, 0x06200050, 0x06200010, 0x06220042, 327 | 0x06030012, 0x80200840, 0x04030040, 0x06000610, 0x06000040, 0x06030220, 0x06030420, 0x06230040, 328 | 0x06210012, 0x06230440, 0x06210412, 0x02220052, 0x80200800, 0x06030040, 0x16000200, 0x16030400, 329 | 0x10000620, 0x02030052, 0x10200240, 0x06200040, 0x00000420, 0x00230040, 0x10000400, 0x00000040, 330 | 0x00000020, 0x84000050, 0x06000450, 0x04000052, 0x10030042, 0x14000050, 0x80000212, 0x00030242, 331 | 0x86000010, 0x80000000, 0x14000800, 0x80000e00, 0x06000000, 0x84020012, 0x84000010, 0x04020052, 332 | 0x06000030, 0x00030202, 0x04000010, 0x00000442, 0x06000050, 0x04020040, 0x14000000, 0x14020400, 333 | 0x10000620, 0x00030842, 0x10000050, 0x10200070, 0x80000800, 0x00200642, 0x10000212, 0x00000000, 334 | 0x04020052, 0x00000012, 0x00000052, 0x00200052, 0x02210232, 0x80220852, 0x10000c12, 0x10000252, 335 | 0x10000400, 0x10020812, 0x80000000, 0x10000800, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 336 | 0x04020052, 0x00000012, 0x04020410, 0x84020012, 0x00200810, 0x02010210, 0x80020042, 0x02200000, 337 | 0x02210812, 0x02200810, 0x80000000, 0x10000800, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 338 | 0x00000000, 0x00030000, 0x00010800, 0x80030852, 0x82220852, 0x92020e32, 0x04200c70, 0x00000800, 339 | 0x00000600, 0x10000020, 0x90000e32, 0x80000812, 0x10000000, 0x00000012, 0x80000000, 0x10000200, 340 | 0x06230050, 0x80000840, 0x00210052, 0x00230050, 0x02030012, 0x00220052, 0x04220052, 0x00230000, 341 | 0x06230052, 0x02210052, 0x80000800, 0x10000800, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 342 | 0x06210842, 0x06000610, 0x06200042, 0x02030800, 0x10200210, 0x16030202, 0x84000a50, 0x02200210, 343 | 0x00200050, 0x00030200, 0x00030250, 0x00210012, 0x00030400, 0x10000042, 0x14000400, 0x10000442, 344 | 0x04020050, 0x06210040, 0x10200200, 0x00030460, 0x00000a20, 0x06030240, 0x80000220, 0x02210012, 345 | 0x10000440, 0x00020c20, 0x10020042, 0x06200040, 0x00000420, 0x00230040, 0x10000400, 0x00000040, 346 | 0x00000020, 0x06000610, 0x06200042, 0x02030800, 0x10200210, 0x16030202, 0x84000a50, 0x02200210, 347 | 0x00200050, 0x00030200, 0x00030250, 0x00210012, 0x00030400, 0x10000042, 0x14000400, 0x10000442, 348 | 0x04020050, 0x06210040, 0x10200200, 0x00030460, 0x00000a20, 0x06030240, 0x80000220, 0x02210012, 349 | 0x10000440, 0x00020c20, 0x10020042, 0x10200070, 0x80000800, 0x00200642, 0x10000212, 0x00000000, 350 | }; 351 | 352 | -------------------------------------------------------------------------------- /s14clock_firmware/s14clock_firmware.ino: -------------------------------------------------------------------------------- 1 | // 2 | // this package is built under windows 10 with platformio 3 | // 4 | // git clone https://github.com/simpleavr/s14clock.git 5 | // cd s14clock 6 | // (pio project init --board lolin_s2_mini) may need to 7 | // (pio lib install AutoConnect) may need to 8 | // pio run --target upload 9 | // pio run -t nobuild -t upload 10 | // 11 | /* 12 | S14Clock is a bar shaped, web synchronized word clock featuring 24 or 12 characters, 14 segment display 13 | platformio is used to build 14 | relies on Arduino AutoConnect library by Hieromon 15 | */ 16 | // 2.01 17 | // c2303 add support for vertical numerics 18 | // c2303 change "glow" transition to "drip" 19 | // 2.02 20 | // c2303 introduce "flash" transition 21 | // c2303 add option to cycle through all transaction modes one after another 22 | // c2304 config time with new time zone immediately after change 23 | // c2305 autodetect v2, v2l, v3 hardware 24 | // c2305 substitute underscore with space for ad-hoc messages 25 | // c2305 ad-hoc messages now follows transition in 26 | // c2306 softAP now uses unique SSID name constructed from chip id 27 | // 28 | // c230501 start v202 29 | // merge / simplify mask vairables 30 | // use direct ESP32 register to setup all IO pins in setupDisply(), no more hard resets needed after flashing 31 | // introduce version 3 hardware, which eliminates use of 74HC154D (4 to 16 line decoder) 32 | // this is done by partial charliplexing the led modules 33 | // c230504 io pin 18 always leaks (looks like S2 chips problem) and introduce ghosting, 34 | // avoid turning on digits for blanks to make it not / less visible 35 | // c230725 implement new token "~+HH" and "~-HH" to add hour offset to current time 36 | // c231108 add optional POSIX TZ string configuration, and allow automatic daylight saving time switching, 37 | // configuration web page now detects geo-location and suggests POSIX TZ string to use 38 | // c231125 add alt_ntp and posix_tz to settings and have them as dedicated configurations for alternate ntp server and posix timezone setup 39 | // c231207 add date countdown 40 | // 0.........0.........0.........0......... 41 | // ~<1225? DAYS PAST: DAYS TIL> CHRISTMAS 42 | // c231210 add ~= token to reversed direction Shift and Drip transitions, i.e. from right to left 43 | // fix bug in ~-?? time offset 44 | // c231227 allow local time in "days counting" content slot 45 | // c240502 change 'alternate transition' token from ~= to ~! 46 | // ~= be used in new ~=0501? HAPPY MAYDAY 47 | // implement alternate transition for "flip" to flip also spaces 48 | // implement alternate transition for "flash" to use alternate sequence 49 | // c250105 fix hardware version detection, V2-24 hardware detection was broken 50 | #define USE_WIFI // comment out to test display only 51 | 52 | 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | #ifdef USE_WIFI 60 | WebServer server; 61 | AutoConnect portal(server); 62 | AutoConnectConfig Config; 63 | #endif 64 | 65 | #define NTPServer1 "pool.ntp.org" 66 | #define NTPServer2 "time1.google.com" 67 | 68 | #include "stdint.h" 69 | // available hardware versions, headers containing IO mapping 70 | #include "map.h" 71 | //#include "ver1.h" 72 | //#include "ver2.h" 73 | //#include "ver2l.h" 74 | //#include "ver3.h" 75 | 76 | #define _LED LED_BUILTIN 77 | #define _BT2 0 78 | 79 | //#include 80 | //#include 81 | //#include 82 | //#include 83 | 84 | hw_timer_t *_timer = 0; 85 | 86 | Preferences prefs; 87 | uint8_t _brightness = 3; 88 | 89 | //____ default hardware is v3-24 character version 90 | uint32_t _chip_id; 91 | char _version[14] = "FW2.03 HW3 "; 92 | uint8_t _num_of_digits = 24; 93 | uint8_t _enable_154 = 0; 94 | uint8_t _charlie = 12; 95 | //uint8_t _detected = 0; 96 | 97 | const uint8_t *digit_map = digit_map_v3; 98 | const uint8_t *digit_map_r = digit_map_r_v3; 99 | 100 | uint32_t segment_mask = segment_mask_v3; 101 | uint32_t all_mask = all_mask_v3; 102 | const uint32_t *spin_mask = spin_mask_v3; 103 | const uint32_t *asciiA = asciiA_v3; 104 | const uint32_t *asciiB = asciiB_v3; 105 | const uint32_t *asciiA_c = asciiA_v3_c; 106 | const uint32_t *asciiB_c = asciiB_v3_c; 107 | 108 | #define DISP_SHUTTER 1 109 | #define DISP_SHIFT 2 110 | #define DISP_DRIP 3 111 | #define DISP_FLIP 4 112 | #define DISP_FLASH 5 113 | #define DISP_SPIN 6 // always make spin last 114 | #define DISP_CLEAR (1<<3) 115 | #define DISP_UPPERCASE (1<<4) 116 | #define DISP_REENTRANT (1<<5) 117 | #define DISP_FORCE (1<<6) 118 | #define DISP_TRANSOPT (1<<7) 119 | 120 | 121 | #define OPT_ROTATED (1<<3) 122 | #define OPT_TOUPPER (1<<4) 123 | #define OPT_NOTUSED (1<<5) 124 | #define OPT_MTRANS (1<<6) 125 | #define OPT_DEMO (1<<7) 126 | 127 | static struct { 128 | char text[9][61]; 129 | char addn[9][25]; 130 | char use[9]; 131 | int8_t timezone; 132 | int8_t brightness; // lower 4 bit used 133 | uint8_t cycle; // seconds to cycle to next content, 0 means no cycling 134 | // options BIT0-2, transition effects, BIT3 rotated display, BIT4 toupper, BIT5 alternate font, BIT6 rotate transition 135 | uint8_t options; 136 | char alt_ntp[61]; 137 | char posix_tz[61]; 138 | char reserved[7]; 139 | } _settings; 140 | 141 | 142 | //static uint8_t _next_transition = 0; 143 | static uint8_t _segment_limit = 0; 144 | 145 | static char _chr_buf[50+24]; 146 | static uint8_t _excess = 0, _excess_shift = 0, _excess_release = 0; 147 | static unsigned _excess_cnt = 0; 148 | // segments io a, b, c...m/2, dp, digits are io 1 to 12 149 | // a b c d e f g G h i j k l m dp 150 | /* 151 | ___ a 152 | f|\|/|b (hij) 153 | - - g G 154 | e|/|\|c (mlk) 155 | === d 156 | */ 157 | static const uint32_t *_font = asciiA; 158 | static const uint8_t *_onOff = asciiOnOff; 159 | 160 | static uint8_t _input = 2; 161 | static int8_t _mode = -1; 162 | static uint16_t _countdown = 0; 163 | static time_t _countfrom = 0; 164 | static uint32_t _dbl_on = 0; 165 | 166 | //________________________________________________________________________________ 167 | void scan() { 168 | // scan() is called at 40Khz, for 1/2 sec count to 20,000 169 | if (++_excess_cnt > 5000) { 170 | _excess_cnt = 0; 171 | if (_excess_release) { // done, we are just retaining last display content 172 | _excess_release = _excess = _excess_shift = 0; 173 | for (uint8_t i=_num_of_digits;i<(50+24);i++) _chr_buf[i] = ' '; 174 | }//if 175 | else { 176 | if (_excess) { 177 | if (_excess_shift < _excess) { 178 | _excess_shift++; // advance string position 179 | }//if 180 | else { 181 | _excess_release = 1; // all done, fix last show for a bit before release 182 | }//else 183 | }//if 184 | }//else 185 | }//if 186 | 187 | static uint8_t d=0, on=0, off=0; 188 | 189 | if (on) { 190 | on--; 191 | return; 192 | }//if 193 | if (_enable_154) { 194 | if (_settings.options&OPT_ROTATED) { 195 | if (d > 15) 196 | pinMode(digit_map_r[d-12], INPUT); 197 | else 198 | digitalWrite(_enable_154, HIGH); 199 | }//if 200 | else { 201 | if (d > 7) 202 | digitalWrite(_enable_154, HIGH); 203 | else 204 | pinMode(digit_map[d], INPUT); 205 | }//else 206 | }//if 207 | else { 208 | REG_WRITE(GPIO_OUT_REG, 0); 209 | REG_WRITE(GPIO_ENABLE_REG, 0); 210 | REG_WRITE(GPIO_OUT1_REG, 0); 211 | REG_WRITE(GPIO_ENABLE1_REG, 0); 212 | }//else 213 | if (off) { 214 | off--; 215 | return; 216 | }//if 217 | 218 | if (++d >= _num_of_digits) d = 0; 219 | uint8_t digit = (_settings.options&OPT_ROTATED) ? _num_of_digits - d - 1 : d; 220 | 221 | if (_enable_154) { 222 | if (digit > 7) { 223 | digitalWrite(_enable_154, HIGH); 224 | }//if 225 | else { 226 | digitalWrite(digit_map[digit], LOW); 227 | pinMode(digit_map[digit], INPUT); 228 | }//if 229 | }//if 230 | uint32_t mask = segment_mask; 231 | if (_charlie && digit >= 12) mask = segment_mask_v3_c; 232 | //if (_charlie && (digit%12) >= 6) mask = segment_mask_v3_c; 233 | 234 | REG_WRITE(GPIO_OUT_W1TC_REG, mask & 0x00ffffff); 235 | REG_WRITE(GPIO_OUT1_W1TC_REG, mask >> 23); 236 | const uint16_t map154[] = 237 | { 11<<5, 12<<5, 13<<5, 14<<5, 10<<5, 5<<5, 4<<5, 6<<5, 7<<5, 8<<5, 9<<5, 15<<5, 2<<5, 1<<5, 0, 3<<5 }; 238 | if (_enable_154) { 239 | REG_WRITE(GPIO_OUT1_W1TC_REG, 0x1e0); 240 | if (digit > 7) { 241 | digitalWrite(_enable_154, LOW); 242 | REG_WRITE(GPIO_OUT1_W1TS_REG, map154[digit-8]); 243 | }//if 244 | }//if 245 | if (_segment_limit) mask = spin_mask[_segment_limit]; 246 | if (_charlie) { 247 | if (_settings.options&OPT_ROTATED) 248 | _font = digit >= 12 ? asciiB_v3_c : asciiB_v3; 249 | else 250 | _font = digit >= 12 ? asciiA_v3_c : asciiA_v3; 251 | }//if 252 | if (!_enable_154) pinMode(digit_map[digit], INPUT); 253 | uint32_t font = _font[_chr_buf[d+_excess_shift]]; 254 | font &= mask; 255 | REG_WRITE(GPIO_OUT_W1TS_REG, font & 0x00ffffff); 256 | if (!_enable_154) REG_WRITE(GPIO_ENABLE_REG, font & 0x00ffffff); 257 | font >>= 23; 258 | REG_WRITE(GPIO_OUT1_W1TS_REG, font); 259 | if (!_enable_154) REG_WRITE(GPIO_ENABLE1_REG, font); 260 | on = _onOff[_chr_buf[d+_excess_shift]]; 261 | if (_dbl_on & (1< 7) { 264 | //on += (on >> 1); 265 | }//if 266 | else { 267 | pinMode(digit_map[digit], OUTPUT); 268 | }//else 269 | }//if 270 | else { 271 | // c230504 don't turn on digit if character is blank 272 | if (on) pinMode(digit_map[digit], OUTPUT); 273 | }//else 274 | //on += _brightness; // potential to increase brightness by skipping blanks 275 | //on += 8*_brightness; 276 | on *= (_brightness+1); 277 | //#endif 278 | //off = 8-_brightness; 279 | if (!_dbl_on || !(_dbl_on & (1<= (_num_of_digits*2)) return; 293 | 294 | uint16_t cmp = 0x0001, segs = 0x0000; 295 | 296 | if ((opt&DISP_UPPERCASE) && v >= 0x61 && v <= 0x7a) v -= 0x20; 297 | // opt>>8 to use numeric set, 1-kanji, 2-flower, 3-vertical 4-aurebesh 298 | // c2303 add support for vertical numerics 299 | //if ((opt&0x0300) && v >= 0x30 && v <= 0x3f) v = (v&0x0f) | ((opt>>8)-1)<<4; 300 | opt >>= 8; 301 | if ((opt&0x03) && v >= 0x30 && v <= 0x3f) { 302 | v &= 0x0f; 303 | switch (opt) { 304 | case 2: v += 1<<4; break; 305 | case 3: v += 9<<4; 306 | default: break; 307 | }//switch 308 | }//if 309 | if (opt&0x04) v += 0x80; // aurebesh, shift full character set 310 | _chr_buf[d] = v; 311 | } 312 | 313 | //________________________________________________________________________________ 314 | uint8_t writeString(const char *s, uint16_t opt=0) { 315 | static char _last_string[64]=""; 316 | static uint16_t _last_opt=0; 317 | static uint8_t _last_transition=0; 318 | 319 | /* 320 | if (_next_transition) { 321 | opt &= 0xfff8; 322 | opt |= _next_transition; 323 | _next_transition = 0; 324 | }//if 325 | */ 326 | if (opt&DISP_FORCE) { 327 | opt &= 0xfff8; 328 | if (_settings.options & OPT_MTRANS) { 329 | _last_transition++; 330 | opt |= _last_transition; 331 | if (_last_transition > DISP_SPIN) 332 | _last_transition = 0; 333 | }//if 334 | else { 335 | opt |= _settings.options&0x07; 336 | }//else 337 | }//if 338 | 339 | if (opt&DISP_CLEAR) clearAll(); 340 | if (opt&DISP_REENTRANT) { 341 | opt &= 0xfff0; // clear effects 342 | }//if 343 | else { 344 | if (!strcmp(s, _last_string) && opt==_last_opt && !(opt&DISP_FORCE)) return 0; 345 | //strcpy(_last_string, s); 346 | //_last_opt = opt; 347 | _excess = _excess_shift = _excess_release = 0; 348 | }//else 349 | switch (opt&0x0f) { 350 | case DISP_SHUTTER: 351 | { 352 | clearAll(); 353 | uint8_t c=1; 354 | if (opt & DISP_TRANSOPT) c++; // double blink 355 | while (c--) { 356 | delay(30); 357 | writeString(s, opt|DISP_REENTRANT); 358 | delay(60); 359 | uint8_t i=0; 360 | const char *p=s; 361 | while (*p) { 362 | writeAscii(i, *p == ' ' ? ' ' : '-', opt); 363 | i++; p++; 364 | }//while 365 | delay(60); 366 | }//while 367 | } 368 | break; 369 | case DISP_SHIFT: 370 | { 371 | //clearAll(); 372 | int8_t dir=1; 373 | if (opt & DISP_TRANSOPT) dir = -1; // right to left 374 | uint8_t j=(_num_of_digits-1); 375 | _last_string[j] = '\0'; 376 | const char *lp = _last_string; 377 | if (dir < 0) lp += j; 378 | while (j--) { 379 | const char *p = lp; 380 | //uint8_t done=0; 381 | //clearAll(); 382 | for (uint8_t i=0;i<24;i++) { 383 | //if (!*p) done = 1; 384 | //writeAscii(i, done ? ' ' : *p, opt); 385 | if (dir > 0) { 386 | if (j == i) p = s; 387 | writeAscii(i, *p ? *p : ' ', opt); 388 | }//if 389 | else { 390 | if (j == i) p = s + _num_of_digits - 1; 391 | writeAscii(23-i, *p ? *p : ' ', opt); 392 | }//else 393 | p += dir; 394 | }//for 395 | lp += dir; 396 | delay(20); 397 | }//while 398 | } 399 | break; 400 | case DISP_DRIP: // right to left 401 | /* 402 | { // this was 'glow' 403 | _brightness = 7; 404 | while (_brightness--) delay(80); 405 | delay(60); 406 | writeString(s, opt|DISP_REENTRANT); 407 | while (_brightness++<=7) delay(80); 408 | _brightness = _settings.brightness&0x07; 409 | } 410 | */ 411 | { 412 | clearAll(); 413 | int8_t dir=1; 414 | if (opt & DISP_TRANSOPT) dir = -1; 415 | const char *p = dir > 0 ? s : s+_num_of_digits-1;; 416 | int8_t j=0; 417 | while (*p) { 418 | if (*p != ' ') { 419 | for (int8_t i=(_num_of_digits-1);i>j;i--) { 420 | int8_t k = dir>0 ? i : _num_of_digits-i-1; 421 | _chr_buf[k] = ' '; 422 | delay(5); 423 | writeAscii(k-dir, *p, opt); 424 | delay(10); 425 | }//for 426 | }//if 427 | j++; 428 | p += dir; 429 | }//while 430 | } 431 | break; 432 | case DISP_FLIP: 433 | { 434 | // 435 | uint8_t done = 0; 436 | const char *a = _last_string; 437 | while (1) { 438 | for (char c='0';c<'Z';c++) { 439 | for (uint8_t i=0;i ' ' || opt & DISP_TRANSOPT) 441 | writeAscii(i, a[i] > c ? (done?c:a[i]) : (done?a[i]:c), opt); 442 | delay(20); 443 | }//for 444 | if (done) break; 445 | clearAll(); 446 | a = s; 447 | done++; 448 | }//while 449 | } 450 | break; 451 | case DISP_SPIN: 452 | { 453 | for (uint8_t i=1;i<14;i++) { 454 | _segment_limit = 14 - i; 455 | delay(30); 456 | }//for 457 | writeString(s, opt|DISP_REENTRANT); 458 | for (uint8_t i=1;i<14;i++) { 459 | _segment_limit = i; 460 | delay(30); 461 | }//for 462 | _segment_limit = 0; 463 | } 464 | break; 465 | case DISP_FLASH: 466 | { 467 | //uint8_t sav_brightness = _brightness; 468 | //_brightness = 0; 469 | uint8_t limit = strlen(s); 470 | const uint8_t mix_map[] = { 471 | 3, 1, 4, 0, 7, 8, 9, 11, 6, 2, 5, 10, 472 | 19, 12, 20, 23, 21, 13, 22, 17, 14, 16, 15, 18, 473 | 7, 8, 9, 11, 6, 2, 5, 10, 3, 1, 4, 0, 474 | 21, 13, 22, 17, 19, 12, 20, 23, 14, 16, 15, 18, 475 | }; 476 | //3, 19, 12, 1, 20, 4, 23, 0, 21, 13, 7, 22, 8, 17, 14, 9, 11, 6, 16, 2, 15, 5, 10, 18, 477 | uint8_t offset = opt & DISP_TRANSOPT ? 0 : 24; 478 | for (uint8_t i=0;i<_num_of_digits;i++) { 479 | uint8_t j = mix_map[(i+s[0])%_num_of_digits + offset]; 480 | if (_chr_buf[j] != ' ') { 481 | if (j < limit && s[j] > ' ') { 482 | writeAscii(j, s[j], opt); 483 | _dbl_on = 1< ' ' && _chr_buf[j] == ' ') { 500 | writeAscii(j, s[j], opt); 501 | _dbl_on = 1< ' ') { 512 | writeAscii(j, s[j], opt); 513 | _dbl_on = j; 514 | delay(50); 515 | _dbl_on = -1; 516 | delay(20); 517 | }//if 518 | else { 519 | if (_chr_buf[j] != ' ') { 520 | _dbl_on = j 521 | delay(50); 522 | _dbl_on = -1; 523 | delay(20); 524 | writeAscii(j, ' ', opt); 525 | }//if 526 | }//else 527 | }//for 528 | */ 529 | } 530 | break; 531 | default: 532 | break; 533 | }//switch 534 | // 535 | if (!(opt&DISP_REENTRANT)) { 536 | strcpy(_last_string, s); 537 | _last_opt = opt; 538 | //________ for excessive characters, we shift them out 539 | if (strlen(s) > _num_of_digits) { 540 | //_excess = (strlen(s) - _num_of_digits); 541 | _excess = strlen(s); 542 | _excess_shift = _excess_release = 0; 543 | _excess_cnt = 0; 544 | }//if 545 | }//if 546 | 547 | uint8_t i=0; 548 | while (*s) writeAscii(i++, *s++, opt); 549 | return (i); 550 | } 551 | 552 | void IRAM_ATTR onTimer() { 553 | scan(); 554 | } 555 | 556 | //________________________________________________________________________________ 557 | void setupDisplay() { 558 | pinMode(_BT2, INPUT_PULLUP); 559 | //pinMode(_LED, OUTPUT); 560 | 561 | gpio_config_t io_cfg; 562 | //io_cfg.pin_bit_mask = all_maskA | ((uint64_t) all_maskB << 32); 563 | io_cfg.pin_bit_mask = (((uint64_t) all_mask >> 23) << 32) | (all_mask & 0x00ffffff); 564 | //io_cfg.pin_bit_mask = (uint64_t) 0x000000ff00ffffff; 565 | io_cfg.mode = GPIO_MODE_INPUT_OUTPUT; 566 | io_cfg.pull_up_en = GPIO_PULLUP_DISABLE; 567 | io_cfg.pull_down_en = GPIO_PULLDOWN_ENABLE; 568 | io_cfg.intr_type = GPIO_INTR_DISABLE; 569 | gpio_config(&io_cfg); 570 | 571 | /* 572 | for (uint8_t i=0;i<12;i++) { 573 | pinMode(s[i], INPUT_PULLDOWN); 574 | //digitalWrite(s[i], HIGH); 575 | }//for 576 | "ver2", 577 | [ 10, 12, 13, 14, 16, 8, 11, 35, 38, 37, 40, 39,], 578 | [ 17, 21, 1, 3, 2, 18, 5, 4, 34, 33, 36, 7, 6, 9, 15,]); # segment S11 and S13 switched in schematic 579 | "ver2l", 580 | [ 34, 16, 17, 18, 21, 33, 36, 35, 37, 38, 39, 40,], 581 | [ 11, 13, 1, 5, 2, 14, 3, 4, 8, 9, 10, 7, 6, 12, 6,]); 582 | "ver3", 583 | [ 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 5, 3, 9, 11,], 584 | [ 33, 18, 7, 8, 14, 36, 13, 12, 39, 38, 15, 2, 11, 9, 11,] 585 | */ 586 | // hardware version detection based on circuit signature S0 + D0 587 | // test segment pins below, segment should be low while digits should be high 588 | pinMode(17, INPUT_PULLUP); 589 | pinMode(10, INPUT_PULLUP); 590 | delay(50); 591 | if ((digitalRead(17) == LOW && digitalRead(10) == HIGH)) { // version 2, 12 characters 592 | //if (digitalRead(17) == LOW && digitalRead(10) == HIGH) _detected = 1; 593 | _enable_154 = 0; 594 | _charlie = 0; 595 | _num_of_digits = 12; 596 | digit_map = digit_map_v2; 597 | digit_map_r = digit_map_r_v2; 598 | segment_mask = segment_mask_v2; 599 | all_mask = all_mask_v2; 600 | spin_mask = spin_mask_v2; 601 | asciiA = asciiA_v2; 602 | asciiB = asciiB_v2; 603 | _version[9] = '2'; 604 | _version[10] = ' '; 605 | _version[11] = ' '; 606 | }//if 607 | pinMode(17, INPUT_PULLDOWN); 608 | pinMode(10, INPUT_PULLDOWN); 609 | //pinMode(11, INPUT_PULLUP); 610 | pinMode(34, INPUT_PULLUP); 611 | delay(50); 612 | if ((digitalRead(11) == LOW && digitalRead(34) == HIGH)) { // version 2, 24 characters 613 | //if (digitalRead(11) == LOW && digitalRead(34) == HIGH) _detected = 1; 614 | _enable_154 = 15; 615 | _charlie = 0; 616 | _num_of_digits = 24; 617 | digit_map = digit_map_v2l; 618 | digit_map_r = digit_map_r_v2l; 619 | segment_mask = segment_mask_v2l; 620 | all_mask = all_mask_v2l; 621 | spin_mask = spin_mask_v2l; 622 | asciiA = asciiA_v2l; 623 | asciiB = asciiB_v2l; 624 | _version[9] = '2'; 625 | _version[10] = 'L'; 626 | _version[11] = ' '; 627 | }//if 628 | /* v3 is default, no need to check 629 | pinMode(33, INPUT_PULLUP); 630 | pinMode(6, INPUT_PULLUP); 631 | if (digitalRead(33) == LOW && digitalRead(6) == LOW) _detected = 1; 632 | */ 633 | 634 | _font = asciiA; 635 | 636 | //io_cfg.pin_bit_mask = all_maskA | ((uint64_t) all_maskB << 32); 637 | io_cfg.pin_bit_mask = (((uint64_t) all_mask >> 23) << 32) | (all_mask & 0x00ffffff); 638 | //io_cfg.mode = GPIO_MODE_INPUT_OUTPUT; 639 | //io_cfg.pull_up_en = GPIO_PULLUP_DISABLE; 640 | //io_cfg.pull_down_en = GPIO_PULLDOWN_ENABLE; 641 | //io_cfg.intr_type = GPIO_INTR_DISABLE; 642 | gpio_config(&io_cfg); 643 | 644 | 645 | //_settings.brightness = 4; 646 | /*______ direct multiplexing 647 | for (uint8_t i=1;i<=18;i++) pinMode(i, OUTPUT); 648 | pinMode(21, OUTPUT); 649 | for (uint8_t i=33;i<=40;i++) pinMode(i, OUTPUT); 650 | REG_WRITE(GPIO_ENABLE_REG, all_maskA);//0b00000000001001111111111111111110); 651 | REG_WRITE(GPIO_ENABLE1_REG, all_maskB);//0b0000000111111110); 652 | pinMode(39, OUTPUT); 653 | pinMode(40, OUTPUT); 654 | */ 655 | if (_enable_154) { 656 | pinMode(_enable_154, OUTPUT); 657 | digitalWrite(_enable_154, HIGH); 658 | }//if 659 | _timer = timerBegin(0, 80, true); 660 | timerAttachInterrupt(_timer, onTimer, true); 661 | timerAlarmWrite(_timer, 25, true); // 25us...40Khz 662 | timerAlarmEnable(_timer); 663 | clearAll(); 664 | } 665 | //________________________________________________________________________________ 666 | 667 | void resetCredentials(void) { 668 | AutoConnectCredential credential; 669 | station_config_t config; 670 | uint8_t ent = credential.entries(); 671 | 672 | Serial.println("AutoConnectCredential deleting"); 673 | if (ent) 674 | Serial.printf("Available %d entries.\n", ent); 675 | else { 676 | Serial.println("No credentials saved."); 677 | return; 678 | } 679 | 680 | while (ent--) { 681 | credential.load((int8_t)0, &config); 682 | if (credential.del((const char*)&config.ssid[0])) 683 | Serial.printf("%s deleted.\n", (const char*)config.ssid); 684 | else 685 | Serial.printf("%s failed to delete.\n", (const char*)config.ssid); 686 | } 687 | } 688 | 689 | void resetConfig() { 690 | strcpy(_settings.text[0], "%b %d %a"); 691 | strcpy(_settings.addn[0], "%R"); 692 | if (_num_of_digits == 24) { 693 | strcpy(_settings.text[1], "~W"); 694 | strcpy(_settings.addn[1], ""); 695 | strcpy(_settings.text[2], "~w"); 696 | strcpy(_settings.addn[2], ""); 697 | }//if 698 | else { 699 | strcpy(_settings.text[1], "~1%X"); 700 | strcpy(_settings.addn[1], ""); 701 | strcpy(_settings.text[2], "~2"); 702 | strcpy(_settings.addn[2], "%X"); 703 | }//else 704 | strcpy(_settings.text[3], "~R"); 705 | strcpy(_settings.addn[3], ""); 706 | strcpy(_settings.text[4], "NEW YORK"); 707 | strcpy(_settings.addn[4], "%T"); 708 | strcpy(_settings.text[5], "~<1225? DAYS TO XMAS"); 709 | strcpy(_settings.addn[5], "%R"); 710 | strcpy(_settings.text[6], "~>191231? DAYS SINCE COVID"); 711 | strcpy(_settings.addn[6], ""); 712 | strcpy(_settings.text[7], "PLS WAIT TO BE SEATED"); 713 | strcpy(_settings.addn[7], ""); 714 | strcpy(_settings.text[8], "BE BACK IN"); 715 | strcpy(_settings.addn[8], "~D"); 716 | _settings.use[0] = _settings.use[1] = _settings.use[5] = _settings.use[6] = 'o'; 717 | _settings.use[2] = _settings.use[3] = _settings.use[4] = _settings.use[7] = ' '; 718 | _settings.use[8] = (char) 1; 719 | _settings.cycle = 6; 720 | _settings.brightness = 2; 721 | _settings.options = OPT_TOUPPER|DISP_FLASH; 722 | //_settings.options &= ~OPT_ROTATED; 723 | _settings.timezone = -4; 724 | } 725 | //________________________________________________________________________________ 726 | void loadConfig() { 727 | _brightness = _settings.brightness; 728 | _brightness &= 0x03; 729 | _font = (_settings.options&OPT_ROTATED) ? asciiB : asciiA; 730 | //_onOff = asciiOnOff; 731 | 732 | } 733 | //________________________________________________________________________________ 734 | void saveConfig() { 735 | _brightness = _settings.brightness; 736 | prefs.end(); 737 | prefs.begin("S14Clock", false); 738 | prefs.putBytes((const char*) "_settings", (void *) &_settings, sizeof(_settings)); 739 | prefs.end(); 740 | prefs.begin("S14Clock", true); 741 | loadConfig(); 742 | //configTime(_settings.timezone * 3600, 0, NTPServer1, NTPServer2); 743 | } 744 | //________________________________________________________________________________ 745 | void configTm() { 746 | const char *ntp = NTPServer1; 747 | if (*_settings.alt_ntp && *_settings.alt_ntp != ' ') ntp = _settings.alt_ntp; 748 | if (*_settings.posix_tz && *_settings.posix_tz != ' ') 749 | configTzTime(_settings.posix_tz, ntp, NTPServer2); 750 | else 751 | configTime(_settings.timezone * 3600, 0, ntp, NTPServer2); 752 | /* 753 | if (*_settings.text[7] == '@' && _settings.use[7] != 'o') 754 | configTime(_settings.timezone * 3600, 0, _settings.text[7] + 1); 755 | else 756 | configTime(_settings.timezone * 3600, 0, NTPServer1, NTPServer2); 757 | // get tz strings with dst here, https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv 758 | //configTzTime("EST5EDT,M3.2.0,M11.1.0", NTPServer1, NTPServer2); 759 | if (_settings.use[7] != 'o') { 760 | // override configuration with TZ string and / or alternate NTP server 761 | const char *ntp = NTPServer1; 762 | if (*_settings.text[7] == '@') 763 | ntp = _settings.text[7] + 1; 764 | if (*_settings.addn[7] == '@') 765 | configTzTime(_settings.addn[7]+1, ntp); 766 | //configTzTime(_settings.addn[7]+1, ntp, NTPServer2); 767 | else 768 | configTime(_settings.timezone * 3600, 0, ntp); 769 | //configTime(_settings.timezone * 3600, 0, ntp, NTPServer2); 770 | }//if 771 | else { 772 | // original configuration 773 | configTime(_settings.timezone * 3600, 0, NTPServer1, NTPServer2); 774 | }//else 775 | */ 776 | } 777 | //________________________________________________________________________________ 778 | void setupClock() { 779 | prefs.begin("S14Clock", true); 780 | if (!prefs.isKey("_settings")) { 781 | resetConfig(); 782 | saveConfig(); 783 | }//if 784 | prefs.getBytes((const char*) "_settings", (void *) &_settings, sizeof(_settings)); 785 | configTm(); 786 | loadConfig(); 787 | } 788 | 789 | 790 | #ifdef USE_WIFI 791 | //________________________________________________________________________________ 792 | void notFound() { 793 | server.send(404, "text/plain", "Not found"); 794 | } 795 | 796 | char htmlResponse[8400]; 797 | 798 | void handleRoot() { 799 | snprintf(htmlResponse, 8400, "\ 800 | \ 801 | \ 808 | \ 809 | \ 810 | \ 811 | \ 812 | \ 813 | \ 814 |
\ 815 | Seg14 Clock\ 816 | \ 817 | \ 818 |
\ 819 | \ 820 |   via AP menu Reset entry\ 821 |

\ 822 | , \ 823 |  \ 824 | \ 827 |

\ 828 |
\ 829 |
\ 830 | Display Contents\ 831 | use ~? (custom), %%? (strtime) tokens
\ 832 | \ 833 | \ 834 | \ 835 | \ 836 | \ 837 | \ 838 | \ 839 | \ 840 | \ 841 | \ 842 | \ 843 | \ 844 | \ 845 | \ 846 | \ 847 | \ 848 | \ 849 | \ 850 | \ 851 | \ 852 | \ 853 | \ 854 | \ 855 | \ 856 | \ 857 | \ 858 | \ 859 | \ 860 | \ 861 | \ 862 | \ 863 | \ 864 | \ 865 | \ 866 | \ 867 | \ 868 | \ 869 | \ 870 | \ 871 | \ 872 | \ 873 | \ 874 | \ 875 | \ 876 | \ 877 | \ 878 | \ 879 | \ 880 | \ 881 | \ 882 | \ 883 | \ 884 | \ 885 | \ 886 | \ 887 | \ 888 | \ 889 | \ 890 | \ 891 | \ 892 | \ 893 |
ContentEnd WithUse
Content (Count Down / Up)#Dd #Uu
NTP Override
Posix TimeZone
\ 894 |

Countdown Increment:
\ 895 | 1 min\ 896 | 5 min\ 897 | 10 min\ 898 | 15 min\ 899 | 30 min\ 900 |

\ 901 |

Transition Effect:
\ 902 | None\ 903 | Blink\ 904 | Shift\ 905 | Drip\ 906 | Flip\ 907 | Flash\ 908 | Spin\ 909 |

\ 910 |

Cycles Contents Every Seconds

\ 911 |

Bright: \ 912 | 0\ 913 | 1\ 914 | 2\ 915 | 3\ 916 | Rotate:

\ 917 | All Caps: \ 918 | Reserved: \ 919 | All Transitions: \ 920 |

\ 921 |

GMT ±hrs (-11..14): \ 922 | (overridable)

\ 923 | \ 924 |   %s\ 925 |
\ 926 |
\ 927 |
\ 928 |
\ 929 |
\ 930 | One-time Message\ 931 | \ 932 | \ 933 |
\ 934 | \ 935 |

\ 936 |
\ 937 | Format Control\ 938 | Formatting tokens can be used in content / message

\ 939 | \ 940 | \ 941 | \ 942 | \ 943 | \ 944 | \ 945 | \ 946 | \ 947 | \ 948 | \ 949 | \ 950 | \ 951 | \ 952 | \ 953 | \ 954 | \ 955 | \ 956 | \ 957 | \ 958 | \ 959 | \ 960 | \ 961 | \ 962 | \ 963 | \ 964 |
TokenEffect on Content / Message
~1Kanji Numerics
~2Flower Code Numerics
~3Vertical Numerics
~4Aurebesh Character Set
~+ddAdd dd hours
~-ddSubtract dd hours
~WWorded Time Format 1
~wWorded Time Format 2
~RRoman Numeric Hour-Min
~rRoman Numeric Hour-Min-Sec
~XMessage expires in 60 seconds
~xMessage expires in 10 seconds
~DCountdown HH:MM:SS
~dCountdown HH:MM
~UCountup HH:MM:SS
~uCountup HH:MM
~!Use alternate transition sequence
~>[[yy]yy]mmdd?Days after date, skip otherwise
~<[[yy]yy]mmdd?Days before date, skip otherwise
~=[[yy]yy]mmdd?Show on exact date, skip otherwise
\ 965 |
Search web for strtime() formatting tokens, common ones includes % + HMSmdw for hour, min, sec, month, day, weekday, etc.
\ 966 |
NTP override and Posix TZ string override (allow automatic daylight saving time) are optional

\ 967 | Useful links
\ 968 | Main project page
\ 969 | Project github page README.md details changes
\ 970 | Project discussions troubleshooting and more
\ 971 | Project wiki page kit building help
\ 972 | Tindie product page if you need more
\ 973 |
\ 974 |

\ 975 | \ 976 | \ 986 | \ 987 | \ 988 | ", 989 | /* TZ format, Olson=America/New_York, POSIX=EST5EDT,M3.2.0/02:00:00,M11.1.0,02:00:00 */ 990 | _settings.text[0], _settings.addn[0], _settings.use[0]=='o' ? "checked" : "", 991 | _settings.text[1], _settings.addn[1], _settings.use[1]=='o' ? "checked" : "", 992 | _settings.text[2], _settings.addn[2], _settings.use[2]=='o' ? "checked" : "", 993 | _settings.text[3], _settings.addn[3], _settings.use[3]=='o' ? "checked" : "", 994 | _settings.text[4], _settings.addn[4], _settings.use[4]=='o' ? "checked" : "", 995 | _settings.text[5], _settings.addn[5], _settings.use[5]=='o' ? "checked" : "", 996 | _settings.text[6], _settings.addn[6], _settings.use[6]=='o' ? "checked" : "", 997 | _settings.text[7], _settings.addn[7], _settings.use[7]=='o' ? "checked" : "", 998 | _settings.text[8], _settings.addn[8], 999 | _settings.alt_ntp, _settings.posix_tz, 1000 | _settings.use[8]<=1 ? "checked" : "", 1001 | _settings.use[8]==5 ? "checked" : "", 1002 | _settings.use[8]==10 ? "checked" : "", 1003 | _settings.use[8]==15 ? "checked" : "", 1004 | _settings.use[8]==30 ? "checked" : "", 1005 | (_settings.options&0x07) == 0 ? "checked" : "", 1006 | (_settings.options&0x07) == 1 ? "checked" : "", 1007 | (_settings.options&0x07) == 2 ? "checked" : "", 1008 | (_settings.options&0x07) == 3 ? "checked" : "", 1009 | (_settings.options&0x07) == 4 ? "checked" : "", 1010 | (_settings.options&0x07) == 5 ? "checked" : "", 1011 | (_settings.options&0x07) == 6 ? "checked" : "", 1012 | _settings.cycle, 1013 | (_settings.brightness&0x03) == 0 ? "checked" : "", 1014 | (_settings.brightness&0x03) == 1 ? "checked" : "", 1015 | (_settings.brightness&0x03) == 2 ? "checked" : "", 1016 | (_settings.brightness&0x03) == 3 ? "checked" : "", 1017 | _settings.options & OPT_ROTATED ? "checked" : "", 1018 | _settings.options & OPT_TOUPPER ? "checked" : "", 1019 | _settings.options & OPT_NOTUSED ? "checked" : "", 1020 | _settings.options & OPT_MTRANS ? "checked" : "", 1021 | _settings.timezone, 1022 | _version 1023 | ); 1024 | 1025 | server.send(200, "text/html", htmlResponse); 1026 | } 1027 | 1028 | void handleButton1() { 1029 | _input = 0x01; 1030 | portal.end(); 1031 | writeString("DEMO", DISP_CLEAR); 1032 | server.sendHeader("Location", "/"); 1033 | server.send(302, "text/plain", "Updated - Press Back Button"); 1034 | } 1035 | 1036 | void handleButton2() { 1037 | _input = 0x02; 1038 | server.sendHeader("Location", "/"); 1039 | server.send(302, "text/plain", "Updated - Press Back Button"); 1040 | } 1041 | 1042 | void showMessage(const char *sp); 1043 | 1044 | void handleFix() { 1045 | showMessage(server.arg("message").c_str()); 1046 | server.sendHeader("Location", "/"); 1047 | server.send(302, "text/plain", "Updated - Press Back Button\n"); 1048 | } 1049 | 1050 | void handleMsg() { 1051 | char msg_buf[50], *p = msg_buf; 1052 | strncpy(msg_buf, server.pathArg(0).c_str(), 48); 1053 | while (*p++) if (*p == '_') *p = ' '; 1054 | showMessage(msg_buf); 1055 | server.sendHeader("Location", "/"); 1056 | server.send(302, "text/plain", "Updated - Press Back Button\n"); 1057 | } 1058 | 1059 | void handleReset() { 1060 | resetConfig(); 1061 | server.sendHeader("Location", "/"); 1062 | server.send(302, "text/plain", "Updated - Press Back Button"); 1063 | saveConfig(); 1064 | } 1065 | 1066 | void handleForm() { 1067 | uint8_t config_time = 0; 1068 | strcpy(_settings.text[0], server.arg("textA").c_str()); 1069 | strcpy(_settings.text[1], server.arg("textB").c_str()); 1070 | strcpy(_settings.text[2], server.arg("textC").c_str()); 1071 | strcpy(_settings.text[3], server.arg("textD").c_str()); 1072 | strcpy(_settings.text[4], server.arg("textE").c_str()); 1073 | strcpy(_settings.text[5], server.arg("textF").c_str()); 1074 | strcpy(_settings.text[6], server.arg("textG").c_str()); 1075 | strcpy(_settings.text[7], server.arg("textH").c_str()); 1076 | strcpy(_settings.text[8], server.arg("textX").c_str()); 1077 | strcpy(_settings.addn[0], server.arg("addnA").c_str()); 1078 | strcpy(_settings.addn[1], server.arg("addnB").c_str()); 1079 | strcpy(_settings.addn[2], server.arg("addnC").c_str()); 1080 | strcpy(_settings.addn[3], server.arg("addnD").c_str()); 1081 | strcpy(_settings.addn[4], server.arg("addnE").c_str()); 1082 | strcpy(_settings.addn[5], server.arg("addnF").c_str()); 1083 | strcpy(_settings.addn[6], server.arg("addnG").c_str()); 1084 | strcpy(_settings.addn[7], server.arg("addnH").c_str()); 1085 | strcpy(_settings.addn[8], server.arg("addnX").c_str()); 1086 | _settings.use[0] = server.arg("useA") != "" ? server.arg("useA")[0] : ' '; 1087 | _settings.use[1] = server.arg("useB") != "" ? server.arg("useB")[0] : ' '; 1088 | _settings.use[2] = server.arg("useC") != "" ? server.arg("useC")[0] : ' '; 1089 | _settings.use[3] = server.arg("useD") != "" ? server.arg("useD")[0] : ' '; 1090 | _settings.use[4] = server.arg("useE") != "" ? server.arg("useE")[0] : ' '; 1091 | _settings.use[5] = server.arg("useF") != "" ? server.arg("useF")[0] : ' '; 1092 | _settings.use[6] = server.arg("useG") != "" ? server.arg("useG")[0] : ' '; 1093 | _settings.use[7] = server.arg("useH") != "" ? server.arg("useH")[0] : ' '; 1094 | _settings.use[8] = (char) (server.arg("useX") != "" ? atoi(server.arg("useX").c_str()) : 1); 1095 | if (strcmp(_settings.alt_ntp, server.arg("altNTP").c_str()) || strcmp(_settings.posix_tz, server.arg("posixTZ").c_str())) 1096 | config_time++; 1097 | strcpy(_settings.alt_ntp, server.arg("altNTP").c_str()); 1098 | strcpy(_settings.posix_tz, server.arg("posixTZ").c_str()); 1099 | _settings.options &= ~0x07; 1100 | _settings.options |= (char) (server.arg("transition") != "" ? atoi(server.arg("transition").c_str()) : 0); 1101 | if (server.arg("cycle")!= "") _settings.cycle = atoi(server.arg("cycle").c_str()); 1102 | if (server.arg("brightness")!= "") _settings.brightness = atoi(server.arg("brightness").c_str()); 1103 | if (server.arg("optRotate")!= "") _settings.options |= OPT_ROTATED; 1104 | else _settings.options &= ~OPT_ROTATED; 1105 | if (server.arg("optToUpper")!= "") _settings.options |= OPT_TOUPPER; 1106 | else _settings.options &= ~OPT_TOUPPER; 1107 | if (server.arg("optXfont")!= "") _settings.options |= OPT_NOTUSED; 1108 | else _settings.options &= ~OPT_NOTUSED; 1109 | if (server.arg("optMtrans")!= "") _settings.options |= OPT_MTRANS; 1110 | else _settings.options &= ~OPT_MTRANS; 1111 | if (server.arg("timezone")!= "") { 1112 | int8_t new_tz = atoi(server.arg("timezone").c_str()); 1113 | // todo detect all tz changes and reload 1114 | if (_settings.timezone != new_tz) { 1115 | _settings.timezone = new_tz; 1116 | config_time++; 1117 | }//if 1118 | }//if 1119 | 1120 | if (config_time) configTm(); 1121 | 1122 | server.sendHeader("Location", "/"); 1123 | server.send(302, "text/plain", "Updated - Press Back Button"); 1124 | saveConfig(); 1125 | //snprintf(htmlResponse, 2048, " Go Back "); 1126 | //server.send(200, "text/html", htmlResponse); 1127 | } 1128 | 1129 | bool waitConnect() { 1130 | static int prev_state = 0; 1131 | static uint32_t s = 0; 1132 | uint32_t c = millis(); 1133 | if ((c-s) > 1000) { 1134 | int curr_state = portal.portalStatus(); 1135 | if (curr_state != prev_state) { 1136 | if (curr_state & AutoConnect::AC_CAPTIVEPORTAL) 1137 | writeString(Config.apid.c_str(), DISP_CLEAR); 1138 | else 1139 | writeString(String(curr_state).c_str(), DISP_CLEAR); 1140 | prev_state = curr_state; 1141 | }//if 1142 | if (_settings.options&OPT_DEMO) { 1143 | return false; 1144 | }//if 1145 | s = c; 1146 | }//if 1147 | return true; 1148 | } 1149 | 1150 | String onRes(AutoConnectAux& aux, PageArgument& args) { 1151 | char buf[20]; 1152 | strcpy(buf, args.arg("epoch").c_str()); 1153 | buf[strlen(buf)-3] = '\0'; 1154 | int epoch = atoi(buf); 1155 | sprintf(buf, "%12d", epoch); 1156 | writeString(buf, DISP_CLEAR|DISP_FORCE); 1157 | struct timeval n; 1158 | n.tv_sec = epoch; 1159 | n.tv_usec = 0; 1160 | settimeofday(&n, NULL); 1161 | _settings.options |= OPT_DEMO; 1162 | return String(); 1163 | } 1164 | 1165 | uint8_t setupWebServer() { 1166 | server.on("/", handleRoot); 1167 | server.on("/fix", handleFix); // example 192.168.2.xx/fix?message=hello world 1168 | server.on("/reset", handleReset); 1169 | server.on("/action_page", handleForm); 1170 | server.on("/button1", handleButton1); 1171 | server.on("/button2", handleButton2); 1172 | server.on("/favicon.ico", notFound); 1173 | server.on(UriRegex("/msg/(.+)"), HTTP_GET, handleMsg); // example 192.168.2.xx/msg/hello_world 1174 | //server.onNotFound(notFound); 1175 | //portal.onNotFound(handleFix1); 1176 | //server.begin(); 1177 | const char PAGE_DEMO[] PROGMEM = R"( { 1178 | "uri": "/demo", 1179 | "title": "Demo", 1180 | "menu": true, 1181 | "element": [ 1182 | { 1183 | "name": "epoch", 1184 | "type": "ACInput", 1185 | "label": "epoch", 1186 | "apply": "number" 1187 | }, 1188 | { 1189 | "name": "run", 1190 | "type": "ACSubmit", 1191 | "value": "RUN", 1192 | "uri": "/demo_on" 1193 | }, 1194 | { 1195 | "name": "js", 1196 | "type": "ACElement", 1197 | "value": "" 1198 | } 1199 | ] 1200 | })"; 1201 | 1202 | const char PAGE_DEMO_ON[] PROGMEM = R"( { 1203 | "uri": "/demo_on", 1204 | "title": "Demo Clock On", 1205 | "menu": false, 1206 | "element": [ 1207 | { 1208 | "name": "content", 1209 | "type": "ACText", 1210 | "value": "Standalone run without WiFi setting." 1211 | } 1212 | ] 1213 | })"; 1214 | 1215 | AutoConnectAux aDemo, aDemo_on; 1216 | aDemo.load(PAGE_DEMO); 1217 | aDemo_on.load(PAGE_DEMO_ON); 1218 | portal.join({aDemo, aDemo_on}); 1219 | portal.on("/demo_on", onRes); 1220 | 1221 | for (int i=0;i<17;i=i+8) _chip_id |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i; 1222 | String cid = String(_chip_id, HEX); 1223 | cid.toUpperCase(); 1224 | 1225 | Config.apid = "ESP-" + cid; 1226 | Config.psk = "12345678"; 1227 | portal.config(Config); 1228 | portal.whileCaptivePortal(waitConnect); 1229 | return portal.begin(); 1230 | } 1231 | 1232 | 1233 | #endif 1234 | 1235 | void macroSub(uint16_t *pOpt, char *dp, const char *sp); 1236 | char* wordTime(char *p, char format); 1237 | 1238 | // 012345678901234567890123 1239 | // TWELVE TWENTY-SEVEN 34 1240 | // SEPTEMBER TWENTY-SEVEN 1241 | // 2022-10-28 FRIDAY 1242 | // 10:28:32 PM TUESDAY 1243 | 1244 | // TWELVE O-CLOCK, O-0NE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE 1245 | // TWELVE TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN, SIXTEEN, SEVENTEEN, EIGHTEEN, NINETEEN 1246 | // TWELVE TWENTY, TWENTY-ONE, ....., TWENTY-NINE 1247 | // TWELVE THIRTY, .., FORTY, .., FIFTY 1248 | //________________________________________________________________________________ 1249 | const char minInc[][12] = { "FIVE", "TEN", "QUARTER", "TWENTY", "TWENTY-FIVE", "HALF", }; 1250 | const char units[][10] = { 1251 | "ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", 1252 | "TEN", "ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN", "FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN", 1253 | }; 1254 | const char tens[][7] = { "TWENTY", "THIRTY", "FORTY", "FIFTY", }; 1255 | const char unitsR[][10] = { "", "\x11", "\x12", "\x13", "\x11V", "V", "V\x11", "V\x12", "V\x13", "\x11X", }; 1256 | const char tensR[][7] = { "", "X", "XX", "XXX", "XL", "L", }; 1257 | 1258 | static time_t _epoch = 0; 1259 | static struct tm *_tm = 0; 1260 | //________________________________________________________________________________ 1261 | char* wordTime(char *p, char format) { 1262 | switch (format) { 1263 | case 'W': 1264 | { 1265 | // #W worded time format 1 1266 | // 012345678901234567890123 1267 | // TWENTY-FIVE PAST TWELVE 1268 | // FIVE,QUARTER,TWENTY-FIVE PAST,TO ... 1269 | uint8_t to=_tm->tm_min>=58 ? 1 : 0; 1270 | _tm->tm_min /= 5; 1271 | // 10:01 past==0, min==0, TEN O'CLOCK 1272 | // 10:31 past==1, min==0, HALF PAST TEN 1273 | if (_tm->tm_min > 6) { 1274 | _tm->tm_hour++; 1275 | to++; 1276 | _tm->tm_min = 12 - _tm->tm_min; 1277 | }//if 1278 | if (_tm->tm_min) strcpy(p, minInc[_tm->tm_min-1]); 1279 | if (to) { 1280 | if (to > 1) 1281 | strcpy(p, "ALMOST "); 1282 | else 1283 | strcat(p, " TO "); 1284 | }//if 1285 | else { 1286 | if (_tm->tm_min) strcat(p, " PAST "); 1287 | }//else 1288 | if ((to>1 || !_tm->tm_min) && !(_tm->tm_hour%12)) { 1289 | //if (_tm->tm_min) _tm->tm_hour--; 1290 | _tm->tm_hour %= 24; 1291 | if (!_tm->tm_hour) 1292 | strcat(p, "MIDNIGHT"); 1293 | else 1294 | strcat(p, "NOON"); 1295 | }//if 1296 | else { 1297 | _tm->tm_hour %= 12; 1298 | if (!_tm->tm_hour) _tm->tm_hour = 12; 1299 | strcat(p, units[_tm->tm_hour]); 1300 | if (!_tm->tm_min) strcat(p, " O'CLOCK "); 1301 | }//else 1302 | break; 1303 | } 1304 | case 'w': { 1305 | // #w worded time format 2 1306 | // 012345678901234567890123 1307 | // TWELVE FORTY-THREE 1308 | _tm->tm_hour %= 12; 1309 | if (_tm->tm_hour == 0) _tm->tm_hour = 12; 1310 | strcat(p, units[_tm->tm_hour]); 1311 | strcat(p, " "); 1312 | if (_tm->tm_min) { 1313 | if (_tm->tm_min >= 20) { 1314 | _tm->tm_min -= 20; 1315 | strcat(p, tens[_tm->tm_min/10]); 1316 | if (_tm->tm_min%10) { 1317 | strcat(p, "'"); 1318 | strcat(p, units[_tm->tm_min%10]); 1319 | }//if 1320 | }//if 1321 | else { 1322 | if (_tm->tm_min < 10) { 1323 | strcat(p, "O'"); 1324 | }//if 1325 | strcat(p, units[_tm->tm_min]); 1326 | }//else 1327 | }//if 1328 | else { 1329 | strcat(p, "O'CLOCK "); 1330 | }//else 1331 | break; 1332 | } 1333 | case 'R': // roman numerics 1334 | case 'r': 1335 | // 12:01, XII.I 1336 | _tm->tm_hour %= 12; 1337 | if (_tm->tm_hour == 0) _tm->tm_hour = 12; 1338 | strcat(p, tensR[_tm->tm_hour/10]); 1339 | strcat(p, unitsR[_tm->tm_hour%10]); 1340 | strcat(p, ","); 1341 | strcat(p, tensR[_tm->tm_min/10]); 1342 | strcat(p, unitsR[_tm->tm_min%10]); 1343 | if (format == 'R') break; 1344 | strcat(p, ","); 1345 | strcat(p, tensR[_tm->tm_sec/10]); 1346 | strcat(p, unitsR[_tm->tm_sec%10]); 1347 | break; 1348 | case 'U': 1349 | case 'u': 1350 | _countdown = _epoch - _countfrom; 1351 | sprintf(p, "%2d:%02d:%02d", _countdown / 3600, (_countdown / 60) % 60, _countdown % 60); 1352 | if (format == 'U') *(p+5) = '\0'; 1353 | break; 1354 | case 'D': 1355 | case 'd': 1356 | sprintf(p, "%2d:%02d:%02d", _countdown / 3600, (_countdown / 60) % 60, _countdown % 60); 1357 | if (format == 'U') *(p+5) = '\0'; 1358 | break; 1359 | case 'X': // expired in 60 seconds 1360 | _countdown += 50; 1361 | case 'x': // expired in 10 seconds 1362 | _countdown += 10; 1363 | _input |= 0x08; 1364 | break; 1365 | default: break; 1366 | }//switch 1367 | _tm = localtime(&_epoch); // _tm already messed up, reload 1368 | while (*p) p++; 1369 | return p; 1370 | } 1371 | 1372 | //________________________________________________________________________________ 1373 | void showMessage(const char *sp) { 1374 | char out1[50] = ""; 1375 | char out2[50] = ""; 1376 | //uint16_t opt = DISP_CLEAR|DISP_FORCE; 1377 | uint16_t opt = DISP_FORCE; 1378 | _input = 0x04; 1379 | //_next_transition = _settings.options&0x07; 1380 | macroSub(&opt, out1, sp); 1381 | strftime(out2, sizeof(out2), out1, _tm); 1382 | clearAll(); 1383 | writeString(out2, opt); 1384 | } 1385 | 1386 | //________________________________________________________________________________ 1387 | void macroSub(uint16_t *pOpt, char *dp, const char *sp) { 1388 | char *dpSav = dp; 1389 | while (*sp) { // process internal # tokens 1st 1390 | if (*sp == '~' && (strchr("~1234WwRrUuDdXx+-!<>=", *(sp+1)))) { 1391 | sp++; 1392 | if (*sp == '~') *dp++ = *sp; 1393 | // c2303 add support for vertical numerics 1394 | //if (strchr("123", *sp)) *pOpt |= 1 << ((*sp - '1') + 8); 1395 | if (strchr("1234", *sp)) *pOpt |= (*sp - '0') << 8; 1396 | if (strchr("WwRrUuDdXx", *sp)) dp = wordTime(dp, *sp); 1397 | // c230725 1398 | if (strchr("+-", *sp) && *(sp+1) >= '0' && *(sp+1) <= '9') { 1399 | int8_t add = *sp=='+' ? 1 : -1; 1400 | sp++; 1401 | int8_t hour_off = 0; 1402 | do { 1403 | hour_off *= 10; 1404 | hour_off += *sp - '0'; 1405 | sp++; 1406 | } while (*sp >= '0' && *sp <= '9'); 1407 | --sp; 1408 | _epoch = time(NULL) + (hour_off * 3600 * add); 1409 | _tm = localtime(&_epoch); 1410 | }//if 1411 | // ~! left-to-right on shift and drip transitions 1412 | if (*sp == '!') { // cc231212 transition direction 1413 | *pOpt |= DISP_TRANSOPT; 1414 | }//if 1415 | // ~<1225? days offset if less than date 1416 | // ~>1225? days offset if greater than date 1417 | if (*sp == '<' || *sp == '>' || *sp == '=') { // cc231207 date counting, cc240502 add exact date or skip 1418 | int yearOn = 0; 1419 | char check = *sp; 1420 | sp++; 1421 | int year_set = -1, century = 1; 1422 | if (*(sp+8) == '?') { // YYYYMMDD? 1423 | century = (*sp-'0') * 10 + (*(++sp)-'0'); 1424 | if (century >= 19) century -= 19; 1425 | else century = 1; // invalid if before 1900, assume 20xx 1426 | sp++; 1427 | }//if 1428 | if (*(sp+6) == '?') { // YYMMDD? 1429 | year_set = (*sp-'0') * 10 + (*(++sp)-'0'); 1430 | year_set += century * 100; 1431 | yearOn++; 1432 | sp++; 1433 | }//if 1434 | if (*(sp+4) == '?') { // MMDD? 1435 | time_t refA=0, refB=0; // refA=current date, refB=target date 1436 | struct tm *tmC = localtime(&_epoch);; 1437 | // set specific date 1438 | tmC->tm_hour = 0; 1439 | tmC->tm_min = 0; 1440 | tmC->tm_sec = 0; 1441 | refA = mktime(tmC); 1442 | if (year_set >= 0) tmC->tm_year = year_set; 1443 | tmC->tm_mon = (*sp-'0') * 10 + (*(++sp)-'0'); 1444 | tmC->tm_mon--; // tm_mon is zero based 1445 | tmC->tm_mday = (*(++sp)-'0') * 10 + (*(++sp)-'0'); 1446 | sp++; 1447 | refB = mktime(tmC); 1448 | int diff = (refA - refB) / (3600 * 24); 1449 | if (!yearOn) { 1450 | if (check == '<' && diff > 0) { // assume next year 1451 | tmC->tm_year++; 1452 | refB = mktime(tmC); 1453 | diff = (refA - refB) / (3600 * 24); 1454 | }//if 1455 | if (check == '>' && diff < 0) { // assume last year 1456 | tmC->tm_year--; 1457 | refB = mktime(tmC); 1458 | diff = (refA - refB) / (3600 * 24); 1459 | }//if 1460 | }//if 1461 | if ((check == '<' && diff <= 0) || (check == '>' && diff >= 0)) { 1462 | sprintf(dp, "%d", labs(diff)); 1463 | dp += strlen(dp); 1464 | }//if 1465 | else { 1466 | if (check != '=' || diff) { // ~=MMDD not matching current date, skip 1467 | dp = dpSav; 1468 | *dp++ = '~'; *dp++ = '~'; // signal to skip show 1469 | break; 1470 | }//if 1471 | }//else 1472 | // cc231227 allow day count content to also show local time 1473 | _epoch = time(NULL); 1474 | _tm = localtime(&_epoch); 1475 | }//if 1476 | }//if 1477 | }//if 1478 | else { 1479 | if (*sp == '%' && *(sp+1) == '-' && (strchr("dmHIMSjuW", *(sp+2)))) { 1480 | // implement zero / space suppression 1481 | sp += 2; 1482 | char token[3], sbuf[16], *p=sbuf; 1483 | token[0] = '%'; 1484 | token[1] = *sp; 1485 | token[2] = '\0'; 1486 | strftime(sbuf, sizeof(sbuf), token, _tm); 1487 | while (*p == '0' || *p == ' ') p++; 1488 | if (!*p && *(p-1) == '0') --p; 1489 | while (*p) *dp++ = *p++; 1490 | }//if 1491 | else { 1492 | *dp++ = *sp; 1493 | }//else 1494 | }//else 1495 | sp++; 1496 | }//while 1497 | *dp = '\0'; 1498 | } 1499 | 1500 | //________________________________________________________________________________ 1501 | int showTime(uint8_t format, uint8_t opt=0) { 1502 | char content[50] = ""; 1503 | char buf[50] = ""; 1504 | uint8_t pos = 0; 1505 | _epoch = time(NULL); 1506 | _tm = localtime(&_epoch); 1507 | 1508 | if (_countdown > 0) { // countdown 1509 | _countdown--; 1510 | format = 8; 1511 | }//if 1512 | uint16_t use_opt = opt; 1513 | char *cp = _settings.text[format]; 1514 | 1515 | if (_settings.options&OPT_TOUPPER) use_opt |= DISP_UPPERCASE; 1516 | 1517 | macroSub(&use_opt, content, cp); 1518 | // "~~" returned from macroSub means to skip, cc231207 1519 | if (content[0] == '~' && content[1] == '~') return 0; 1520 | strftime(buf, sizeof(buf), content, _tm); 1521 | 1522 | pos = strlen(buf); 1523 | if (pos < _num_of_digits) { 1524 | char rbuf[50] = ""; 1525 | cp = _settings.addn[format]; 1526 | *content = '\0'; 1527 | 1528 | macroSub(&use_opt, content, cp); 1529 | strftime(rbuf, sizeof(rbuf), content, _tm); 1530 | while (pos < (_num_of_digits-strlen(rbuf))) buf[pos++] = ' '; 1531 | if ((pos + strlen(rbuf)) > _num_of_digits) pos = _num_of_digits - strlen(rbuf); 1532 | buf[pos] = '\0'; 1533 | strcat(buf, rbuf); 1534 | //buf[_num_of_digits] = '\0'; 1535 | }//if 1536 | 1537 | writeString(buf, use_opt); 1538 | return 1; 1539 | } 1540 | // 1541 | 1542 | /* experiment w/ class inheritance 1543 | 1544 | class LEDBar : public Stream { 1545 | private: 1546 | int pos=0; 1547 | int advance=0; 1548 | public: 1549 | int read() { return 0; } 1550 | int available() { return 0; } 1551 | int peek() { return 0; } 1552 | virtual size_t write(uint8_t val) { 1553 | if (val == 0x0d || val == 0x0a) { 1554 | advance = 1; 1555 | }//if 1556 | else { 1557 | if (advance) { 1558 | advance = 0; 1559 | pos = 0; 1560 | clearAll(); 1561 | }//if 1562 | writeAscii(pos, val, 1); 1563 | if (++pos>23) pos = 0; 1564 | }//else 1565 | return 1; 1566 | } 1567 | virtual size_t write(const uint8_t *buf, uint8_t val) { writeString((char*) buf); return val; } 1568 | using Print::write; 1569 | virtual void flush() { } 1570 | }; 1571 | 1572 | 1573 | LEDBar _timeBar; 1574 | */ 1575 | 1576 | 1577 | 1578 | //________________________________________________________________________________ 1579 | void setup() { 1580 | 1581 | setupDisplay(); 1582 | 1583 | 1584 | writeString("OOOOOOOOOOOOOOOOOOOOOOOO"); 1585 | delay(700); 1586 | bool resettingCredentials = false; 1587 | uint8_t countDown = 3; 1588 | unsigned long msNow = millis(); 1589 | if(digitalRead(_BT2) == LOW){ 1590 | if (_num_of_digits == 12) 1591 | writeString("3s TO RESET", DISP_CLEAR); 1592 | else 1593 | writeString("HOLD 3s TO RESET", DISP_CLEAR); 1594 | } 1595 | while (digitalRead(_BT2) == LOW){ 1596 | unsigned long elapsed = millis() - msNow; 1597 | if ((millis() - msNow) > 1000) { 1598 | countDown--; 1599 | msNow = millis(); 1600 | writeAscii(_num_of_digits == 12 ? 0 : 5, countDown + '0'); 1601 | if (!countDown) { 1602 | delay(200); 1603 | resettingCredentials = true; 1604 | resetCredentials(); 1605 | break; 1606 | }//if 1607 | }//if 1608 | }//while 1609 | if (resettingCredentials) { 1610 | for(uint8_t sc = 0; sc < 3; sc++){ 1611 | if (_num_of_digits == 12) 1612 | writeString("WIFI CLEARED", DISP_CLEAR); 1613 | else 1614 | writeString("WIFI SETTINGS CLEARED", DISP_CLEAR); 1615 | delay(500); 1616 | writeString("", DISP_CLEAR); 1617 | delay(500); 1618 | } 1619 | delay(500); 1620 | } 1621 | writeString("************************"); 1622 | delay(400); 1623 | clearAll(); 1624 | writeString(_version); 1625 | uint8_t burn_in = 0; 1626 | uint32_t current_time = millis(); 1627 | while ((millis() - current_time) < 2000) { 1628 | if (digitalRead(_BT2) == LOW) { 1629 | while (digitalRead(_BT2) == LOW) { // wait for key release 1630 | delay(10); 1631 | }//while 1632 | burn_in = 1; 1633 | writeString("BURN IN TEST"); 1634 | }//if 1635 | }//while 1636 | clearAll(); 1637 | #ifdef USE_WIFI 1638 | if (!burn_in) { 1639 | writeString("CONNECTING..", DISP_CLEAR); 1640 | if (setupWebServer()) { 1641 | char buf[24]; 1642 | sprintf(buf, "%s", WiFi.localIP().toString().c_str()); 1643 | writeString(buf, DISP_CLEAR); 1644 | }//if 1645 | else { 1646 | _settings.options &= ~OPT_DEMO; 1647 | writeString("STANDALONE", DISP_CLEAR); 1648 | burn_in = 1; 1649 | }//else 1650 | delay(2000); 1651 | }//if 1652 | #else 1653 | //if (_detected) 1654 | //writeString("DETECTED", DISP_CLEAR); 1655 | //else 1656 | writeString("NO WIFI", DISP_CLEAR); 1657 | delay(1000); 1658 | #endif 1659 | setupClock(); 1660 | // burn-in or debug use 1661 | //resetConfig(); 1662 | //saveConfig(); 1663 | //_input = 0x04; 1664 | if (burn_in) { 1665 | resetConfig(); 1666 | /*--- uncomment for testing only ------------------------------------------------- 1667 | struct timeval n; 1668 | n.tv_sec = 1714521600; // baseline date 2024-05-01 midnight 1669 | n.tv_sec += 4 * 3600; // adjust timezone 1670 | n.tv_sec -= 20; 1671 | n.tv_usec = 0; 1672 | settimeofday(&n, NULL); 1673 | _settings.use[0] = 'o'; _settings.use[1] = 'o'; 1674 | _settings.use[2] = ' '; _settings.use[3] = ' '; 1675 | _settings.use[4] = ' '; _settings.use[5] = ' '; 1676 | _settings.use[5] = ' '; _settings.use[6] = ' '; 1677 | strcpy(_settings.text[0], "~!%b %d %a"); 1678 | strcpy(_settings.addn[0], "%X"); 1679 | strcpy(_settings.text[1], "~!~W"); 1680 | strcpy(_settings.text[5], "~<1225? DAYS TO XMAS"); 1681 | strcpy(_settings.text[6], "~!~=0501?HAPPY MAYDAY"); 1682 | _brightness = 3; 1683 | _settings.cycle = 6; 1684 | _settings.options = OPT_TOUPPER; 1685 | //strcpy(_settings.text[1], "~-3%X"); 1686 | //strcpy(_settings.text[2], "~+10"); 1687 | //strcpy(_settings.text[3], "~4%X"); 1688 | //_settings.options |= DISP_SHIFT; 1689 | //_settings.options |= DISP_SHUTTER; 1690 | //_settings.options |= DISP_FLIP; 1691 | //_settings.options |= DISP_SPIN; 1692 | _settings.options |= DISP_FLASH; 1693 | //_settings.options |= OPT_MTRANS; 1694 | /*----------------------------------------------------------------------------*/ 1695 | }//if 1696 | } 1697 | static int _count = 0; 1698 | //________________________________________________________________________________ 1699 | void loop() { 1700 | static uint8_t cycle = _settings.cycle; 1701 | static uint32_t save_time = 0; 1702 | static uint32_t stay_in_3_until = 0; 1703 | uint32_t current_time = millis(); 1704 | uint8_t opt = 0; 1705 | 1706 | if (digitalRead(_BT2) == LOW) { 1707 | while (digitalRead(_BT2) == LOW) { // wait for key release 1708 | if ((millis() - current_time) > 500) { 1709 | //__________ release after 1/2 second, considered as long pressed 1710 | _input = 3; 1711 | writeString("-", DISP_CLEAR); // indicate press-n-hold achieved 1712 | while (digitalRead(_BT2) == LOW); // wait for final release 1713 | }//if 1714 | }//while 1715 | if (stay_in_3_until) _input = 3; // single key press following a press-n-hold consider as press-n-hold 1716 | if (_input != 3) { // not press-n-hold 1717 | // ____ __________ _____ 1718 | // |__| |__| 1719 | // <--400ms--> 1720 | //key_last_pressed = millis(); // wait for next key or time registers 1721 | _input = 2; 1722 | delay(150); // hold 250ms, if comeback 1723 | for (uint8_t i=0;i<10 && (digitalRead(_BT2) != LOW);i++) { 1724 | delay(10); 1725 | }//for 1726 | if (digitalRead(_BT2) == LOW) { 1727 | while (digitalRead(_BT2) == LOW); 1728 | _input = 1; 1729 | }//if 1730 | }//if 1731 | }//if 1732 | else { 1733 | if (stay_in_3_until) { 1734 | if (current_time > stay_in_3_until) { 1735 | stay_in_3_until = 0; 1736 | saveConfig(); 1737 | //_next_transition = _settings.options&0x07; // force transition 1738 | opt |= DISP_FORCE; 1739 | cycle = _settings.cycle; 1740 | }//if 1741 | else { 1742 | return; // wait for press-n-hold succession to expire 1743 | }//else 1744 | }//if 1745 | }//else 1746 | 1747 | if (_input == 3) stay_in_3_until = millis() + 1000; 1748 | if (_input & 0x03) current_time += 1000; // force immediate action 1749 | 1750 | const char _transit_label[][10] = { "-NONE", "-SHUTTER", "-SHIFT", "-DRIP", "-FLIP", "-FLASH", "-SPIN", }; 1751 | switch (_input) { 1752 | case 1: // increment countdown minutes 1753 | if (!_settings.use[8]) _settings.use[8] = 1; 1754 | _countdown += _settings.use[8] * 60; 1755 | _countfrom = time(NULL) - 1; 1756 | break; 1757 | case 2: // cycle display content 1758 | { 1759 | if (_countdown) { 1760 | _countdown = 0; 1761 | }//if 1762 | else { // not long pressed 1763 | ++_mode %= 8; 1764 | uint8_t check=_mode; 1765 | while (_settings.use[_mode] != 'o') { 1766 | ++_mode %= 8; 1767 | //_________ use slot 0 if none is setup 1768 | if (check==_mode) _settings.use[0] = 'o'; 1769 | }//while 1770 | cycle = _settings.cycle; 1771 | //_next_transition = _settings.options&0x07; 1772 | }//else 1773 | opt |= DISP_FORCE; 1774 | } 1775 | break; 1776 | case 3: // long pressed button 2 1777 | _countdown = 0; 1778 | if ((_settings.options&0x07) == DISP_SPIN) _settings.options &= ~0x07; 1779 | else _settings.options++; 1780 | //saveConfig(); 1781 | writeString(_transit_label[_settings.options&0x07], DISP_CLEAR); 1782 | _input = 0; 1783 | return; 1784 | /* 1785 | delay(1000); 1786 | _next_transition = _settings.options&0x07; // force transition 1787 | cycle = _settings.cycle; 1788 | */ 1789 | break; 1790 | //case 4: // showing one time message 1791 | default: 1792 | break; 1793 | }//switch 1794 | _input &= ~0x03; // clear button actions 1795 | //_____ update display 1796 | if ((current_time - save_time) > 1000) { // second passed 1797 | // every second we do this 1798 | save_time = current_time; 1799 | if (!_input) { // normal mode, check to automatic cycling of contents 1800 | showTime(_mode, opt); 1801 | if (cycle) { 1802 | cycle--; 1803 | }//if 1804 | else { 1805 | if (_settings.cycle && !_countdown) { // advance content, set timer for next advance 1806 | _input = 2; 1807 | cycle = _settings.cycle; 1808 | //_next_transition = _settings.options&0x07; 1809 | }//if 1810 | }//else 1811 | }//if 1812 | else { // in fixed message mode 1813 | if (_input & 0x08) { // with expiry 1814 | if (_countdown) _countdown--; 1815 | else _input = 2; // advance 1816 | }//if 1817 | }//else 1818 | }//if 1819 | #ifdef USE_WIFI 1820 | portal.handleClient(); 1821 | #endif 1822 | delay(1); // suppose to save a lot of power 1823 | // 1824 | } 1825 | -------------------------------------------------------------------------------- /s14clock_firmware/ver1.h: -------------------------------------------------------------------------------- 1 | const uint8_t digit_map[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, }; 2 | const uint8_t digit_map_r[] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, }; 3 | 4 | #define NUM_OF_DIGITS 12 5 | const uint32_t segment_mask = 0x7f27e000; 6 | const uint32_t all_mask = 0x7f27fffe; 7 | const uint32_t spin_mask[] = { 8 | 0x00002000, 0x00006000, 0x0000e000, 0x0001e000, 9 | 0x0003e000, 0x0007e000, 0x0027e000, 0x0127e000, 10 | 0x0327e000, 0x0727e000, 0x0f27e000, 0x4f27e000, 11 | 0x6f27e000, 0x7f27e000, 0x7f27e000, }; 12 | const uint32_t asciiA[] = { 13 | 0x01238000, 0x01200000, 0x01210000, 0x01212000, 0x0b246000, 0x2521a000, 0x55200000, 0x15210000, 14 | 0x50000000, 0x15208000, 0x20000000, 0x14000000, 0x48200000, 0x01210000, 0x13000000, 0x21006000, 15 | 0x01246000, 0x24000000, 0x2400c000, 0x2406c000, 0x5a000000, 0x1301a000, 0x05200000, 0x05210000, 16 | 0x05212000, 0x5a002000, 0x20000000, 0x14000000, 0x48200000, 0x01210000, 0x13000000, 0x21006000, 17 | 0x00000000, 0x0000c000, 0x04004000, 0x2521c000, 0x2525a000, 0x7f248000, 0x46232000, 0x04000000, 18 | 0x48000000, 0x12000000, 0x7f200000, 0x25200000, 0x10000000, 0x01200000, 0x20000000, 0x18000000, 19 | 0x1807e000, 0x0800c000, 0x01236000, 0x0101e000, 0x0124c000, 0x40252000, 0x0127a000, 0x0000e000, 20 | 0x0127e000, 0x0125e000, 0x20000000, 0x14000000, 0x48200000, 0x01210000, 0x13000000, 0x21006000, 21 | 0x05076000, 0x0126e000, 0x2501e000, 0x00072000, 0x2401e000, 0x00272000, 0x00262000, 0x0107a000, 22 | 0x0126c000, 0x24012000, 0x0003c000, 0x48260000, 0x00070000, 0x0a06c000, 0x4206c000, 0x0007e000, 23 | 0x01266000, 0x4007e000, 0x41266000, 0x0125a000, 0x24002000, 0x0007c000, 0x18060000, 0x5006c000, 24 | 0x5a000000, 0x0125c000, 0x18012000, 0x00072000, 0x42000000, 0x0001e000, 0x50000000, 0x00010000, 25 | 0x02000000, 0x20230000, 0x40270000, 0x01230000, 0x1101c000, 0x10230000, 0x29200000, 0x0901c000, 26 | 0x20260000, 0x20000000, 0x14020000, 0x6c000000, 0x00060000, 0x21228000, 0x20220000, 0x01238000, 27 | 0x02260000, 0x0900c000, 0x00220000, 0x41010000, 0x00270000, 0x00038000, 0x10020000, 0x50028000, 28 | 0x5a000000, 0x0501c000, 0x10210000, 0x12212000, 0x24000000, 0x49012000, 0x19200000, 0x00000000, 29 | 0x00000000, 0x01200000, 0x01210000, 0x01212000, 0x0b246000, 0x2521a000, 0x55200000, 0x19210000, 30 | 0x50000000, 0x15208000, 0x20000000, 0x14000000, 0x48200000, 0x01210000, 0x13000000, 0x21006000, 31 | 0x01238000, 0x01200000, 0x40228000, 0x21228000, 0x04202000, 0x08244000, 0x21018000, 0x00042000, 32 | 0x05246000, 0x04242000, 0x20000000, 0x14000000, 0x48200000, 0x01210000, 0x13000000, 0x21006000, 33 | 0x00000000, 0x0000c000, 0x04004000, 0x2521c000, 0x2525a000, 0x7f248000, 0x46232000, 0x04000000, 34 | 0x48000000, 0x12000000, 0x7f200000, 0x25200000, 0x10000000, 0x01200000, 0x20000000, 0x18000000, 35 | 0x0027e000, 0x24010000, 0x01216000, 0x0021e000, 0x0124c000, 0x0121a000, 0x0123a000, 0x0000e000, 36 | 0x0127e000, 0x01256000, 0x24000000, 0x14000000, 0x48200000, 0x01210000, 0x13000000, 0x21006000, 37 | 0x05076000, 0x48260000, 0x01072000, 0x0404c000, 0x18202000, 0x1906c000, 0x2c230000, 0x08242000, 38 | 0x00212000, 0x0800c000, 0x0821c000, 0x01206000, 0x4000c000, 0x11010000, 0x50020000, 0x51010000, 39 | 0x00238000, 0x00076000, 0x18002000, 0x4201c000, 0x0e000000, 0x0807c000, 0x2a000000, 0x01246000, 40 | 0x50010000, 0x46008000, 0x11018000, 0x00072000, 0x42000000, 0x0001e000, 0x50000000, 0x00010000, 41 | 0x02000000, 0x48260000, 0x01072000, 0x0404c000, 0x18202000, 0x1906c000, 0x2c230000, 0x08242000, 42 | 0x00212000, 0x0800c000, 0x0821c000, 0x01206000, 0x4000c000, 0x11010000, 0x50020000, 0x51010000, 43 | 0x00238000, 0x00076000, 0x18002000, 0x4201c000, 0x0e000000, 0x0807c000, 0x2a000000, 0x01246000, 44 | 0x50010000, 0x46008000, 0x11018000, 0x12212000, 0x24000000, 0x49012000, 0x19200000, 0x00000000, 45 | }; 46 | 47 | const uint32_t asciiB[] = { 48 | 0x01246000, 0x01200000, 0x01202000, 0x01212000, 0x51238000, 0x25252000, 0x2b200000, 0x29202000, 49 | 0x0a000000, 0x29240000, 0x04000000, 0x28000000, 0x13000000, 0x01202000, 0x48200000, 0x04230000, 50 | 0x01238000, 0x24000000, 0x24060000, 0x2406c000, 0x5a000000, 0x48252000, 0x21200000, 0x21202000, 51 | 0x21212000, 0x5a010000, 0x04000000, 0x28000000, 0x13000000, 0x01202000, 0x48200000, 0x04230000, 52 | 0x00000000, 0x00060000, 0x20020000, 0x25262000, 0x2525a000, 0x7f248000, 0x63016000, 0x20000000, 53 | 0x12000000, 0x48000000, 0x7f200000, 0x25200000, 0x08000000, 0x01200000, 0x04000000, 0x18000000, 54 | 0x1807e000, 0x10060000, 0x01236000, 0x00272000, 0x01268000, 0x0301a000, 0x0125e000, 0x00070000, 55 | 0x0127e000, 0x0127a000, 0x04000000, 0x28000000, 0x13000000, 0x01202000, 0x48200000, 0x04230000, 56 | 0x2023e000, 0x0127c000, 0x24272000, 0x0001e000, 0x24072000, 0x0101e000, 0x0101c000, 0x0025e000, 57 | 0x0126c000, 0x24012000, 0x00066000, 0x1300c000, 0x0000e000, 0x5006c000, 0x4206c000, 0x0007e000, 58 | 0x0123c000, 0x0207e000, 0x0323c000, 0x0125a000, 0x24010000, 0x0006e000, 0x1800c000, 0x0a06c000, 59 | 0x5a000000, 0x0126a000, 0x18012000, 0x0001e000, 0x42000000, 0x00072000, 0x0a000000, 0x00002000, 60 | 0x40000000, 0x05006000, 0x0300e000, 0x01206000, 0x08262000, 0x09006000, 0x15200000, 0x10262000, 61 | 0x0500c000, 0x04000000, 0x28004000, 0x36000000, 0x0000c000, 0x05244000, 0x05004000, 0x01246000, 62 | 0x4100c000, 0x10260000, 0x01004000, 0x02202000, 0x0100e000, 0x00046000, 0x08004000, 0x0a044000, 63 | 0x5a000000, 0x20262000, 0x09002000, 0x49012000, 0x24000000, 0x12212000, 0x19200000, 0x00000000, 64 | 0x00000000, 0x01200000, 0x01202000, 0x01212000, 0x51238000, 0x25252000, 0x2b200000, 0x19202000, 65 | 0x0a000000, 0x29240000, 0x04000000, 0x28000000, 0x13000000, 0x01202000, 0x48200000, 0x04230000, 66 | 0x01246000, 0x01200000, 0x03044000, 0x05244000, 0x21010000, 0x11028000, 0x04242000, 0x00018000, 67 | 0x21238000, 0x21018000, 0x04000000, 0x28000000, 0x13000000, 0x01202000, 0x48200000, 0x04230000, 68 | 0x00000000, 0x00060000, 0x20020000, 0x25262000, 0x2525a000, 0x7f248000, 0x63016000, 0x20000000, 69 | 0x12000000, 0x48000000, 0x7f200000, 0x25200000, 0x08000000, 0x01200000, 0x04000000, 0x18000000, 70 | 0x0107e000, 0x24002000, 0x01232000, 0x01072000, 0x01268000, 0x01252000, 0x01256000, 0x00070000, 71 | 0x0127e000, 0x0123a000, 0x24000000, 0x28000000, 0x13000000, 0x01202000, 0x48200000, 0x04230000, 72 | 0x2023e000, 0x1300c000, 0x0021e000, 0x20068000, 0x19010000, 0x1826c000, 0x35006000, 0x11018000, 73 | 0x01012000, 0x10060000, 0x11062000, 0x01230000, 0x02060000, 0x08202000, 0x0a004000, 0x0a202000, 74 | 0x01046000, 0x0003e000, 0x18010000, 0x42062000, 0x70000000, 0x1006e000, 0x54000000, 0x01238000, 75 | 0x0a002000, 0x62040000, 0x08242000, 0x0001e000, 0x42000000, 0x00072000, 0x0a000000, 0x00002000, 76 | 0x40000000, 0x1300c000, 0x0021e000, 0x20068000, 0x19010000, 0x1826c000, 0x35006000, 0x11018000, 77 | 0x01012000, 0x10060000, 0x11062000, 0x01230000, 0x02060000, 0x08202000, 0x0a004000, 0x0a202000, 78 | 0x01046000, 0x0003e000, 0x18010000, 0x42062000, 0x70000000, 0x1006e000, 0x54000000, 0x01238000, 79 | 0x0a002000, 0x62040000, 0x08242000, 0x49012000, 0x24000000, 0x12212000, 0x19200000, 0x00000000, 80 | }; 81 | 82 | const uint8_t asciiOnOff[] = { 83 | 0x05, 0x02, 0x03, 0x04, 0x07, 0x07, 0x05, 0x05, 84 | 0x02, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 85 | 0x05, 0x02, 0x04, 0x06, 0x04, 0x06, 0x03, 0x04, 86 | 0x05, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 87 | 0x00, 0x02, 0x02, 0x07, 0x08, 0x0a, 0x07, 0x01, 88 | 0x02, 0x02, 0x08, 0x04, 0x01, 0x02, 0x01, 0x02, 89 | 0x08, 0x03, 0x06, 0x05, 0x05, 0x05, 0x07, 0x03, 90 | 0x08, 0x07, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 91 | 0x07, 0x07, 0x07, 0x04, 0x06, 0x05, 0x04, 0x06, 92 | 0x06, 0x04, 0x04, 0x05, 0x03, 0x06, 0x06, 0x06, 93 | 0x06, 0x07, 0x07, 0x06, 0x03, 0x05, 0x04, 0x06, 94 | 0x04, 0x06, 0x04, 0x04, 0x02, 0x04, 0x02, 0x01, 95 | 0x01, 0x04, 0x05, 0x04, 0x05, 0x04, 0x04, 0x05, 96 | 0x04, 0x01, 0x03, 0x04, 0x02, 0x05, 0x03, 0x05, 97 | 0x04, 0x04, 0x02, 0x03, 0x04, 0x03, 0x02, 0x04, 98 | 0x04, 0x05, 0x03, 0x05, 0x02, 0x05, 0x04, 0x00, 99 | 0x00, 0x02, 0x03, 0x04, 0x07, 0x07, 0x05, 0x05, 100 | 0x02, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 101 | 0x05, 0x02, 0x04, 0x05, 0x03, 0x04, 0x04, 0x02, 102 | 0x06, 0x04, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 103 | 0x00, 0x02, 0x02, 0x07, 0x08, 0x0a, 0x07, 0x01, 104 | 0x02, 0x02, 0x08, 0x04, 0x01, 0x02, 0x01, 0x02, 105 | 0x07, 0x03, 0x05, 0x05, 0x05, 0x05, 0x06, 0x03, 106 | 0x08, 0x06, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 107 | 0x07, 0x05, 0x05, 0x04, 0x04, 0x07, 0x06, 0x04, 108 | 0x03, 0x03, 0x05, 0x04, 0x03, 0x03, 0x03, 0x04, 109 | 0x04, 0x05, 0x03, 0x05, 0x03, 0x06, 0x03, 0x05, 110 | 0x03, 0x04, 0x04, 0x04, 0x02, 0x04, 0x02, 0x01, 111 | 0x01, 0x05, 0x05, 0x04, 0x04, 0x07, 0x06, 0x04, 112 | 0x03, 0x03, 0x05, 0x04, 0x03, 0x03, 0x03, 0x04, 113 | 0x04, 0x05, 0x03, 0x05, 0x03, 0x06, 0x03, 0x05, 114 | 0x03, 0x04, 0x04, 0x05, 0x02, 0x05, 0x04, 0x00, 115 | }; 116 | 117 | -------------------------------------------------------------------------------- /s14clock_firmware/ver2.h: -------------------------------------------------------------------------------- 1 | const uint8_t digit_map[] = { 10, 12, 13, 14, 16, 8, 11, 35, 38, 37, 40, 39, }; 2 | const uint8_t digit_map_r[] = { 39, 40, 37, 38, 35, 11, 8, 16, 14, 13, 12, 10, }; 3 | 4 | #define NUM_OF_DIGITS 12 5 | const uint32_t segment_mask = 0x0b2682fe; 6 | const uint32_t all_mask = 0xff27fffe; 7 | const uint32_t spin_mask[] = { 8 | 0x00020000, 0x00220000, 0x00220002, 0x0022000a, 9 | 0x0022000e, 0x0026000e, 0x0026002e, 0x0026003e, 10 | 0x0226003e, 0x0326003e, 0x0b26003e, 0x0b2600be, 11 | 0x0b2600fe, 0x0b2602fe, 0x0b2682fe, }; 12 | const uint32_t asciiA[] = { 13 | 0x0000003e, 0x00000030, 0x00000038, 0x00020038, 0x0a260030, 0x0102007a, 0x010002b0, 0x01000238, 14 | 0x00000280, 0x01000232, 0x00000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 15 | 0x00260030, 0x01000040, 0x01200042, 0x01240046, 0x0a000280, 0x0202021a, 0x01000030, 0x01000038, 16 | 0x01020038, 0x0a020280, 0x00000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 17 | 0x00000000, 0x00200002, 0x01200000, 0x0120007a, 0x0106007a, 0x0b0402f2, 0x030200ac, 0x01000000, 18 | 0x08000080, 0x02000200, 0x0b0002f0, 0x01000070, 0x00000200, 0x00000030, 0x00000040, 0x08000200, 19 | 0x0826020e, 0x08200002, 0x0022003c, 0x0022001a, 0x00240032, 0x000600a8, 0x0006003e, 0x00220002, 20 | 0x0026003e, 0x0026003a, 0x00000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 21 | 0x0126001c, 0x00260036, 0x0122005a, 0x0006000c, 0x0122004a, 0x0006002c, 0x00060024, 0x0006001e, 22 | 0x00240036, 0x01020048, 0x0020000e, 0x080400a4, 0x0004000c, 0x0a240006, 0x02240086, 0x0026000e, 23 | 0x00260034, 0x0026008e, 0x002600b4, 0x0006003a, 0x01020040, 0x0024000e, 0x08040204, 0x00240286, 24 | 0x0a000280, 0x0024003a, 0x08020208, 0x0006000c, 0x02000080, 0x0022000a, 0x00000280, 0x00000008, 25 | 0x02000000, 0x0000006c, 0x000400ac, 0x0000003c, 0x0020021a, 0x0000022c, 0x08000070, 0x0820001a, 26 | 0x00040064, 0x00000040, 0x01000204, 0x090000c0, 0x00040004, 0x00000076, 0x00000064, 0x0000003e, 27 | 0x02040024, 0x08200012, 0x00000024, 0x00000098, 0x0004002c, 0x0000000e, 0x00000204, 0x00000286, 28 | 0x0a000280, 0x0120001a, 0x00000228, 0x02020228, 0x01000040, 0x08020098, 0x08000230, 0x00000000, 29 | 0x00000000, 0x00000030, 0x00000038, 0x00020038, 0x0a260030, 0x0102007a, 0x010002b0, 0x08000238, 30 | 0x00000280, 0x01000232, 0x00000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 31 | 0x0000003e, 0x00000030, 0x000000a6, 0x00000076, 0x01020020, 0x08240020, 0x0000005a, 0x00060000, 32 | 0x01260030, 0x01060020, 0x00000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 33 | 0x00000000, 0x00200002, 0x01200000, 0x0120007a, 0x0106007a, 0x0b0402f2, 0x030200ac, 0x01000000, 34 | 0x08000080, 0x02000200, 0x0b0002f0, 0x01000070, 0x00000200, 0x00000030, 0x00000040, 0x08000200, 35 | 0x0026002e, 0x01000048, 0x00220038, 0x0022002a, 0x00240032, 0x0002003a, 0x0002003e, 0x00220002, 36 | 0x0026003e, 0x00260038, 0x01000040, 0x01000200, 0x080000a0, 0x00000038, 0x02000210, 0x00220050, 37 | 0x0126001c, 0x080400a4, 0x0006001c, 0x01240002, 0x08020220, 0x08240216, 0x0900006c, 0x08060020, 38 | 0x00020028, 0x08200002, 0x0820002a, 0x00220030, 0x00200082, 0x00000218, 0x00000284, 0x00000298, 39 | 0x0000002e, 0x0026000c, 0x08020200, 0x0220008a, 0x0b000000, 0x0824000e, 0x0a000040, 0x00260030, 40 | 0x00000288, 0x03000082, 0x0000021a, 0x0006000c, 0x02000080, 0x0022000a, 0x00000280, 0x00000008, 41 | 0x02000000, 0x080400a4, 0x0006001c, 0x01240002, 0x08020220, 0x08240216, 0x0900006c, 0x08060020, 42 | 0x00020028, 0x08200002, 0x0820002a, 0x00220030, 0x00200082, 0x00000218, 0x00000284, 0x00000298, 43 | 0x0000002e, 0x0026000c, 0x08020200, 0x0220008a, 0x0b000000, 0x0824000e, 0x0a000040, 0x00260030, 44 | 0x00000288, 0x03000082, 0x0000021a, 0x02020228, 0x01000040, 0x08020098, 0x08000230, 0x00000000, 45 | }; 46 | 47 | const uint32_t asciiB[] = { 48 | 0x00260030, 0x00000030, 0x00020030, 0x00020038, 0x000002be, 0x01060078, 0x0a000070, 0x08020070, 49 | 0x0a000000, 0x08040070, 0x01000000, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 50 | 0x0000003e, 0x01000040, 0x01040044, 0x01240046, 0x0a000280, 0x080600a8, 0x00000070, 0x00020070, 51 | 0x00020078, 0x0a000288, 0x01000000, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 52 | 0x00000000, 0x00040004, 0x00000044, 0x01060074, 0x0106007a, 0x0b0402f2, 0x022200d8, 0x00000040, 53 | 0x02000200, 0x08000080, 0x0b0002f0, 0x01000070, 0x08000000, 0x00000030, 0x01000000, 0x08000200, 54 | 0x0826020e, 0x00040204, 0x0022003c, 0x0006002c, 0x00040036, 0x0202001a, 0x0026003a, 0x0004000c, 55 | 0x0026003e, 0x0006003e, 0x01000000, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 56 | 0x0022006e, 0x0024003e, 0x0106006c, 0x0022000a, 0x0106004c, 0x0022001a, 0x0020001a, 0x0026002a, 57 | 0x00240036, 0x01020048, 0x00260004, 0x02200212, 0x00220002, 0x00240286, 0x02240086, 0x0026000e, 58 | 0x0020003e, 0x0226000e, 0x0220003e, 0x0006003a, 0x01000048, 0x00260006, 0x08200202, 0x0a240006, 59 | 0x0a000280, 0x00060036, 0x08020208, 0x0022000a, 0x02000080, 0x0006000c, 0x0a000000, 0x00020000, 60 | 0x00000080, 0x01220010, 0x02220012, 0x00220030, 0x08060024, 0x08220010, 0x01000230, 0x00060224, 61 | 0x01200012, 0x01000000, 0x08200040, 0x03000240, 0x00200002, 0x01240030, 0x01200010, 0x00260030, 62 | 0x00200092, 0x00040224, 0x00200010, 0x02020020, 0x00220012, 0x00260000, 0x08200000, 0x0a240000, 63 | 0x0a000280, 0x00060064, 0x08020010, 0x08020098, 0x01000040, 0x02020228, 0x08000230, 0x00000000, 64 | 0x00000000, 0x00000030, 0x00020030, 0x00020038, 0x000002be, 0x01060078, 0x0a000070, 0x08020230, 65 | 0x0a000000, 0x08040070, 0x01000000, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 66 | 0x00260030, 0x00000030, 0x02240010, 0x01240030, 0x00000058, 0x00000216, 0x01060020, 0x0000000a, 67 | 0x0000007e, 0x0000005a, 0x01000000, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 68 | 0x00000000, 0x00040004, 0x00000044, 0x01060074, 0x0106007a, 0x0b0402f2, 0x022200d8, 0x00000040, 69 | 0x02000200, 0x08000080, 0x0b0002f0, 0x01000070, 0x08000000, 0x00000030, 0x01000000, 0x08000200, 70 | 0x0026001e, 0x01020040, 0x0002003c, 0x0006001c, 0x00040036, 0x00060038, 0x00260038, 0x0004000c, 71 | 0x0026003e, 0x0002003e, 0x01000040, 0x08000040, 0x02000210, 0x00020030, 0x080000a0, 0x0100002c, 72 | 0x0022006e, 0x02200212, 0x0022002a, 0x00040046, 0x08000218, 0x08240226, 0x01220250, 0x0000021a, 73 | 0x00020018, 0x00040204, 0x00060214, 0x0000003c, 0x02040004, 0x08020020, 0x0a200000, 0x0a020020, 74 | 0x00260010, 0x0022000e, 0x08000208, 0x02060084, 0x000002c0, 0x00260206, 0x01000280, 0x0000003e, 75 | 0x0a020000, 0x020400c0, 0x08060020, 0x0022000a, 0x02000080, 0x0006000c, 0x0a000000, 0x00020000, 76 | 0x00000080, 0x02200212, 0x0022002a, 0x00040046, 0x08000218, 0x08240226, 0x01220250, 0x0000021a, 77 | 0x00020018, 0x00040204, 0x00060214, 0x0000003c, 0x02040004, 0x08020020, 0x0a200000, 0x0a020020, 78 | 0x00260010, 0x0022000e, 0x08000208, 0x02060084, 0x000002c0, 0x00260206, 0x01000280, 0x0000003e, 79 | 0x0a020000, 0x020400c0, 0x08060020, 0x08020098, 0x01000040, 0x02020228, 0x08000230, 0x00000000, 80 | }; 81 | 82 | const uint8_t asciiOnOff[] = { 83 | 0x05, 0x02, 0x03, 0x04, 0x07, 0x07, 0x05, 0x05, 84 | 0x02, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 85 | 0x05, 0x02, 0x04, 0x06, 0x04, 0x06, 0x03, 0x04, 86 | 0x05, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 87 | 0x00, 0x02, 0x02, 0x07, 0x08, 0x0a, 0x07, 0x01, 88 | 0x02, 0x02, 0x08, 0x04, 0x01, 0x02, 0x01, 0x02, 89 | 0x08, 0x03, 0x06, 0x05, 0x05, 0x05, 0x07, 0x03, 90 | 0x08, 0x07, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 91 | 0x07, 0x07, 0x07, 0x04, 0x06, 0x05, 0x04, 0x06, 92 | 0x06, 0x04, 0x04, 0x05, 0x03, 0x06, 0x06, 0x06, 93 | 0x06, 0x07, 0x07, 0x06, 0x03, 0x05, 0x04, 0x06, 94 | 0x04, 0x06, 0x04, 0x04, 0x02, 0x04, 0x02, 0x01, 95 | 0x01, 0x04, 0x05, 0x04, 0x05, 0x04, 0x04, 0x05, 96 | 0x04, 0x01, 0x03, 0x04, 0x02, 0x05, 0x03, 0x05, 97 | 0x04, 0x04, 0x02, 0x03, 0x04, 0x03, 0x02, 0x04, 98 | 0x04, 0x05, 0x03, 0x05, 0x02, 0x05, 0x04, 0x00, 99 | 0x00, 0x02, 0x03, 0x04, 0x07, 0x07, 0x05, 0x05, 100 | 0x02, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 101 | 0x05, 0x02, 0x04, 0x05, 0x03, 0x04, 0x04, 0x02, 102 | 0x06, 0x04, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 103 | 0x00, 0x02, 0x02, 0x07, 0x08, 0x0a, 0x07, 0x01, 104 | 0x02, 0x02, 0x08, 0x04, 0x01, 0x02, 0x01, 0x02, 105 | 0x07, 0x03, 0x05, 0x05, 0x05, 0x05, 0x06, 0x03, 106 | 0x08, 0x06, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 107 | 0x07, 0x05, 0x05, 0x04, 0x04, 0x07, 0x06, 0x04, 108 | 0x03, 0x03, 0x05, 0x04, 0x03, 0x03, 0x03, 0x04, 109 | 0x04, 0x05, 0x03, 0x05, 0x03, 0x06, 0x03, 0x05, 110 | 0x03, 0x04, 0x04, 0x04, 0x02, 0x04, 0x02, 0x01, 111 | 0x01, 0x05, 0x05, 0x04, 0x04, 0x07, 0x06, 0x04, 112 | 0x03, 0x03, 0x05, 0x04, 0x03, 0x03, 0x03, 0x04, 113 | 0x04, 0x05, 0x03, 0x05, 0x03, 0x06, 0x03, 0x05, 114 | 0x03, 0x04, 0x04, 0x05, 0x02, 0x05, 0x04, 0x00, 115 | }; 116 | 117 | -------------------------------------------------------------------------------- /s14clock_firmware/ver2l.h: -------------------------------------------------------------------------------- 1 | const uint8_t digit_map[] = { 34, 16, 17, 18, 21, 33, 36, 35, 37, 38, 39, 40, }; 2 | const uint8_t digit_map_r[] = { 40, 39, 38, 37, 35, 36, 33, 21, 18, 17, 16, 34, }; 3 | 4 | #define ENABLE_154 15 5 | #define NUM_OF_DIGITS 24 6 | const uint32_t segment_mask = 0x00007ffe; 7 | const uint32_t all_mask = 0xff277ffe; 8 | const uint32_t spin_mask[] = { 9 | 0x00000800, 0x00002800, 0x00002802, 0x00002822, 10 | 0x00002826, 0x00006826, 0x0000682e, 0x0000683e, 11 | 0x0000693e, 0x00006b3e, 0x00006f3e, 0x00006fbe, 12 | 0x00006ffe, 0x00007ffe, 0x00007ffe, }; 13 | const uint32_t asciiA[] = { 14 | 0x0000003e, 0x00000018, 0x00000038, 0x00000838, 0x00006d18, 0x00000a7a, 0x00001298, 0x00001238, 15 | 0x00001080, 0x0000121a, 0x00000040, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 16 | 0x00006818, 0x00000240, 0x00002242, 0x00006246, 0x00001580, 0x00001932, 0x00000218, 0x00000238, 17 | 0x00000a38, 0x00001d80, 0x00000040, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 18 | 0x00000000, 0x00002002, 0x00002200, 0x0000227a, 0x00004a7a, 0x000057da, 0x00000bac, 0x00000200, 19 | 0x00000480, 0x00001100, 0x000017d8, 0x00000258, 0x00001000, 0x00000018, 0x00000040, 0x00001400, 20 | 0x00007c26, 0x00002402, 0x0000283c, 0x00002832, 0x0000601a, 0x000048a8, 0x0000483e, 0x00002802, 21 | 0x0000683e, 0x0000683a, 0x00000040, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 22 | 0x00006a34, 0x0000681e, 0x00002a72, 0x00004824, 0x00002a62, 0x0000482c, 0x0000480c, 0x00004836, 23 | 0x0000601e, 0x00000a60, 0x00002026, 0x0000448c, 0x00004024, 0x00006506, 0x00006186, 0x00006826, 24 | 0x0000681c, 0x000068a6, 0x0000689c, 0x0000483a, 0x00000a40, 0x00006026, 0x00005404, 0x00007086, 25 | 0x00001580, 0x0000603a, 0x00001c20, 0x00004824, 0x00000180, 0x00002822, 0x00001080, 0x00000020, 26 | 0x00000100, 0x0000006c, 0x000040ac, 0x0000003c, 0x00003032, 0x0000102c, 0x00000458, 0x00002432, 27 | 0x0000404c, 0x00000040, 0x00001204, 0x000006c0, 0x00004004, 0x0000005e, 0x0000004c, 0x0000003e, 28 | 0x0000410c, 0x00002412, 0x0000000c, 0x000000b0, 0x0000402c, 0x00000026, 0x00001004, 0x00001086, 29 | 0x00001580, 0x00002232, 0x00001028, 0x00001928, 0x00000240, 0x00000cb0, 0x00001418, 0x00000000, 30 | 0x00000000, 0x00000018, 0x00000038, 0x00000838, 0x00006d18, 0x00000a7a, 0x00001298, 0x00001438, 31 | 0x00001080, 0x0000121a, 0x00000040, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 32 | 0x0000003e, 0x00000018, 0x0000008e, 0x0000005e, 0x00000a08, 0x00006408, 0x00000072, 0x00004800, 33 | 0x00006a18, 0x00004a08, 0x00000040, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 34 | 0x00000000, 0x00002002, 0x00002200, 0x0000227a, 0x00004a7a, 0x000057da, 0x00000bac, 0x00000200, 35 | 0x00000480, 0x00001100, 0x000017d8, 0x00000258, 0x00001000, 0x00000018, 0x00000040, 0x00001400, 36 | 0x0000682e, 0x00000260, 0x00002838, 0x0000282a, 0x0000601a, 0x0000083a, 0x0000083e, 0x00002802, 37 | 0x0000683e, 0x00006838, 0x00000240, 0x00001200, 0x00000488, 0x00000038, 0x00001110, 0x00002850, 38 | 0x00006a34, 0x0000448c, 0x00004834, 0x00006202, 0x00001c08, 0x00007416, 0x0000066c, 0x00004c08, 39 | 0x00000828, 0x00002402, 0x0000242a, 0x00002818, 0x00002082, 0x00001030, 0x00001084, 0x000010b0, 40 | 0x0000002e, 0x00006824, 0x00001c00, 0x000021a2, 0x00000700, 0x00006426, 0x00000540, 0x00006818, 41 | 0x000010a0, 0x00000382, 0x00001032, 0x00004824, 0x00000180, 0x00002822, 0x00001080, 0x00000020, 42 | 0x00000100, 0x0000448c, 0x00004834, 0x00006202, 0x00001c08, 0x00007416, 0x0000066c, 0x00004c08, 43 | 0x00000828, 0x00002402, 0x0000242a, 0x00002818, 0x00002082, 0x00001030, 0x00001084, 0x000010b0, 44 | 0x0000002e, 0x00006824, 0x00001c00, 0x000021a2, 0x00000700, 0x00006426, 0x00000540, 0x00006818, 45 | 0x000010a0, 0x00000382, 0x00001032, 0x00001928, 0x00000240, 0x00000cb0, 0x00001418, 0x00000000, 46 | }; 47 | 48 | const uint32_t asciiB[] = { 49 | 0x00006818, 0x00000018, 0x00000818, 0x00000838, 0x000010be, 0x00004a78, 0x00000558, 0x00000c58, 50 | 0x00000500, 0x00004458, 0x00000200, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 51 | 0x0000003e, 0x00000240, 0x00004244, 0x00006246, 0x00001580, 0x00004ca8, 0x00000058, 0x00000858, 52 | 0x00000878, 0x000015a0, 0x00000200, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 53 | 0x00000000, 0x00004004, 0x00000044, 0x00004a5c, 0x00004a7a, 0x000057da, 0x000029f0, 0x00000040, 54 | 0x00001100, 0x00000480, 0x000017d8, 0x00000258, 0x00000400, 0x00000018, 0x00000200, 0x00001400, 55 | 0x00007c26, 0x00005004, 0x0000283c, 0x0000482c, 0x0000401e, 0x00000932, 0x0000683a, 0x00004024, 56 | 0x0000683e, 0x0000483e, 0x00000200, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 57 | 0x0000286e, 0x0000603e, 0x00004a6c, 0x00002822, 0x00004a64, 0x00002832, 0x00002032, 0x0000682a, 58 | 0x0000601e, 0x00000a60, 0x00006804, 0x00003112, 0x00002802, 0x00007086, 0x00006186, 0x00006826, 59 | 0x0000203e, 0x00006926, 0x0000213e, 0x0000483a, 0x00000260, 0x00006806, 0x00003402, 0x00006506, 60 | 0x00001580, 0x0000481e, 0x00001c20, 0x00002822, 0x00000180, 0x00004824, 0x00000500, 0x00000800, 61 | 0x00000080, 0x00002a10, 0x00002912, 0x00002818, 0x00004c0c, 0x00002c10, 0x00001218, 0x0000580c, 62 | 0x00002212, 0x00000200, 0x00002440, 0x00001340, 0x00002002, 0x00006218, 0x00002210, 0x00006818, 63 | 0x00002092, 0x0000500c, 0x00002010, 0x00000908, 0x00002812, 0x00006800, 0x00002400, 0x00006500, 64 | 0x00001580, 0x0000484c, 0x00000c10, 0x00000cb0, 0x00000240, 0x00001928, 0x00001418, 0x00000000, 65 | 0x00000000, 0x00000018, 0x00000818, 0x00000838, 0x000010be, 0x00004a78, 0x00000558, 0x00001c18, 66 | 0x00000500, 0x00004458, 0x00000200, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 67 | 0x00006818, 0x00000018, 0x00006110, 0x00006218, 0x00000070, 0x00001016, 0x00004a08, 0x00000022, 68 | 0x0000007e, 0x00000072, 0x00000200, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 69 | 0x00000000, 0x00004004, 0x00000044, 0x00004a5c, 0x00004a7a, 0x000057da, 0x000029f0, 0x00000040, 70 | 0x00001100, 0x00000480, 0x000017d8, 0x00000258, 0x00000400, 0x00000018, 0x00000200, 0x00001400, 71 | 0x00006836, 0x00000a40, 0x0000083c, 0x00004834, 0x0000401e, 0x00004838, 0x00006838, 0x00004024, 72 | 0x0000683e, 0x0000083e, 0x00000240, 0x00000440, 0x00001110, 0x00000818, 0x00000488, 0x0000022c, 73 | 0x0000286e, 0x00003112, 0x0000282a, 0x00004046, 0x00001430, 0x0000740e, 0x00003a50, 0x00001032, 74 | 0x00000830, 0x00005004, 0x00005814, 0x0000003c, 0x00004104, 0x00000c08, 0x00002500, 0x00000d08, 75 | 0x00006810, 0x00002826, 0x00001420, 0x00004984, 0x000010c0, 0x00007806, 0x00001280, 0x0000003e, 76 | 0x00000d00, 0x000041c0, 0x00004c08, 0x00002822, 0x00000180, 0x00004824, 0x00000500, 0x00000800, 77 | 0x00000080, 0x00003112, 0x0000282a, 0x00004046, 0x00001430, 0x0000740e, 0x00003a50, 0x00001032, 78 | 0x00000830, 0x00005004, 0x00005814, 0x0000003c, 0x00004104, 0x00000c08, 0x00002500, 0x00000d08, 79 | 0x00006810, 0x00002826, 0x00001420, 0x00004984, 0x000010c0, 0x00007806, 0x00001280, 0x0000003e, 80 | 0x00000d00, 0x000041c0, 0x00004c08, 0x00000cb0, 0x00000240, 0x00001928, 0x00001418, 0x00000000, 81 | }; 82 | 83 | const uint8_t asciiOnOff[] = { 84 | 0x05, 0x02, 0x03, 0x04, 0x07, 0x07, 0x05, 0x05, 85 | 0x02, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 86 | 0x05, 0x02, 0x04, 0x06, 0x04, 0x06, 0x03, 0x04, 87 | 0x05, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 88 | 0x00, 0x02, 0x02, 0x07, 0x08, 0x0a, 0x07, 0x01, 89 | 0x02, 0x02, 0x08, 0x04, 0x01, 0x02, 0x01, 0x02, 90 | 0x08, 0x03, 0x06, 0x05, 0x05, 0x05, 0x07, 0x03, 91 | 0x08, 0x07, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 92 | 0x07, 0x07, 0x07, 0x04, 0x06, 0x05, 0x04, 0x06, 93 | 0x06, 0x04, 0x04, 0x05, 0x03, 0x06, 0x06, 0x06, 94 | 0x06, 0x07, 0x07, 0x06, 0x03, 0x05, 0x04, 0x06, 95 | 0x04, 0x06, 0x04, 0x04, 0x02, 0x04, 0x02, 0x01, 96 | 0x01, 0x04, 0x05, 0x04, 0x05, 0x04, 0x04, 0x05, 97 | 0x04, 0x01, 0x03, 0x04, 0x02, 0x05, 0x03, 0x05, 98 | 0x04, 0x04, 0x02, 0x03, 0x04, 0x03, 0x02, 0x04, 99 | 0x04, 0x05, 0x03, 0x05, 0x02, 0x05, 0x04, 0x00, 100 | 0x00, 0x02, 0x03, 0x04, 0x07, 0x07, 0x05, 0x05, 101 | 0x02, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 102 | 0x05, 0x02, 0x04, 0x05, 0x03, 0x04, 0x04, 0x02, 103 | 0x06, 0x04, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 104 | 0x00, 0x02, 0x02, 0x07, 0x08, 0x0a, 0x07, 0x01, 105 | 0x02, 0x02, 0x08, 0x04, 0x01, 0x02, 0x01, 0x02, 106 | 0x07, 0x03, 0x05, 0x05, 0x05, 0x05, 0x06, 0x03, 107 | 0x08, 0x06, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 108 | 0x07, 0x05, 0x05, 0x04, 0x04, 0x07, 0x06, 0x04, 109 | 0x03, 0x03, 0x05, 0x04, 0x03, 0x03, 0x03, 0x04, 110 | 0x04, 0x05, 0x03, 0x05, 0x03, 0x06, 0x03, 0x05, 111 | 0x03, 0x04, 0x04, 0x04, 0x02, 0x04, 0x02, 0x01, 112 | 0x01, 0x05, 0x05, 0x04, 0x04, 0x07, 0x06, 0x04, 113 | 0x03, 0x03, 0x05, 0x04, 0x03, 0x03, 0x03, 0x04, 114 | 0x04, 0x05, 0x03, 0x05, 0x03, 0x06, 0x03, 0x05, 115 | 0x03, 0x04, 0x04, 0x05, 0x02, 0x05, 0x04, 0x00, 116 | }; 117 | 118 | -------------------------------------------------------------------------------- /s14clock_firmware/ver3.h: -------------------------------------------------------------------------------- 1 | const uint8_t digit_map[] = { 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 5, 33, 18, 7, 8, 14, 36, 13, 12, 39, 38, 15, 2, }; 2 | const uint8_t digit_map_r[] = { 2, 15, 38, 39, 12, 13, 36, 14, 8, 7, 18, 33, 5, 37, 40, 10, 4, 1, 17, 16, 21, 34, 35, 6, }; 3 | 4 | #define NUM_OF_DIGITS 24 5 | #define CHARLIE 12 6 | const uint32_t segment_mask = 0x6904fb84; 7 | const uint32_t all_mask = 0xff27fffe; 8 | const uint32_t spin_mask[] = { 9 | 0x01000000, 0x01040000, 0x01040080, 0x01040180, 10 | 0x01044180, 0x09044180, 0x09046180, 0x09047180, 11 | 0x49047180, 0x69047180, 0x6904f180, 0x6904f184, 12 | 0x6904f984, 0x6904fb84, 0x6904fb84, }; 13 | const uint32_t asciiA[] = { 14 | 0x00007180, 0x00003000, 0x00003100, 0x01003100, 0x4904b000, 0x21003980, 0x20003204, 0x20003300, 15 | 0x00000204, 0x20003280, 0x00000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01041800, 16 | 0x09043000, 0x20000800, 0x20040880, 0x28044880, 0x40008204, 0x41001380, 0x20003000, 0x20003100, 17 | 0x21003100, 0x41008204, 0x00000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01041800, 18 | 0x00000000, 0x00040080, 0x20040000, 0x20043980, 0x29003980, 0x6800ba84, 0x61006104, 0x20000000, 19 | 0x00008004, 0x40000200, 0x6000ba04, 0x20003800, 0x00000200, 0x00003000, 0x00000800, 0x00008200, 20 | 0x0904c380, 0x00048080, 0x01047100, 0x01041180, 0x08043080, 0x09002104, 0x09007180, 0x01040080, 21 | 0x09047180, 0x09043180, 0x00000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01041800, 22 | 0x29045100, 0x09047080, 0x21041980, 0x09004100, 0x21040980, 0x09006100, 0x09006000, 0x09005180, 23 | 0x08047080, 0x21000900, 0x00044180, 0x0800e004, 0x08004100, 0x4804c080, 0x48044084, 0x09044180, 24 | 0x09047000, 0x09044184, 0x09047004, 0x09003180, 0x21000800, 0x08044180, 0x0800c200, 0x08044284, 25 | 0x40008204, 0x08043180, 0x01008300, 0x09004100, 0x40000004, 0x01040180, 0x00000204, 0x00000100, 26 | 0x40000000, 0x00006900, 0x08006104, 0x00007100, 0x00041380, 0x00006300, 0x0000b800, 0x00049180, 27 | 0x08006800, 0x00000800, 0x20004200, 0x20008804, 0x08004000, 0x00007880, 0x00006800, 0x00007180, 28 | 0x48006000, 0x00049080, 0x00006000, 0x00001104, 0x08006100, 0x00004180, 0x00004200, 0x00004284, 29 | 0x40008204, 0x20041180, 0x00002300, 0x41002300, 0x20000800, 0x01009104, 0x0000b200, 0x00000000, 30 | 0x00000000, 0x00003000, 0x00003100, 0x01003100, 0x4904b000, 0x21003980, 0x20003204, 0x0000b300, 31 | 0x00000204, 0x20003280, 0x00000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01041800, 32 | 0x00007180, 0x00003000, 0x00006084, 0x00007880, 0x21002000, 0x0804a000, 0x00001980, 0x09000000, 33 | 0x29043000, 0x29002000, 0x00000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01041800, 34 | 0x00000000, 0x00040080, 0x20040000, 0x20043980, 0x29003980, 0x6800ba84, 0x61006104, 0x20000000, 35 | 0x00008004, 0x40000200, 0x6000ba04, 0x20003800, 0x00000200, 0x00003000, 0x00000800, 0x00008200, 36 | 0x09046180, 0x20000900, 0x01043100, 0x01042180, 0x08043080, 0x01003180, 0x01007180, 0x01040080, 37 | 0x09047180, 0x09043100, 0x20000800, 0x20000200, 0x0000a004, 0x00003100, 0x40001200, 0x01041800, 38 | 0x29045100, 0x0800e004, 0x09005100, 0x28040080, 0x0100a200, 0x0804d280, 0x2000e900, 0x0900a000, 39 | 0x01002100, 0x00048080, 0x0004a180, 0x01043000, 0x00040084, 0x00001300, 0x00004204, 0x00001304, 40 | 0x00006180, 0x09044100, 0x01008200, 0x40040184, 0x60008000, 0x0804c180, 0x40008800, 0x09043000, 41 | 0x00000304, 0x60000084, 0x00001380, 0x09004100, 0x40000004, 0x01040180, 0x00000204, 0x00000100, 42 | 0x40000000, 0x0800e004, 0x09005100, 0x28040080, 0x0100a200, 0x0804d280, 0x2000e900, 0x0900a000, 43 | 0x01002100, 0x00048080, 0x0004a180, 0x01043000, 0x00040084, 0x00001300, 0x00004204, 0x00001304, 44 | 0x00006180, 0x09044100, 0x01008200, 0x40040184, 0x60008000, 0x0804c180, 0x40008800, 0x09043000, 45 | 0x00000304, 0x60000084, 0x00001380, 0x41002300, 0x20000800, 0x01009104, 0x0000b200, 0x00000000, 46 | }; 47 | 48 | const uint32_t asciiB[] = { 49 | 0x09043000, 0x00003000, 0x01003000, 0x01003100, 0x00007384, 0x29003900, 0x4000b800, 0x0100b800, 50 | 0x40008000, 0x0800b800, 0x20000000, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 51 | 0x00007180, 0x20000800, 0x28004800, 0x28044880, 0x40008204, 0x0900a104, 0x00003800, 0x01003800, 52 | 0x01003900, 0x40008304, 0x20000000, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 53 | 0x00000000, 0x08004000, 0x00004800, 0x29007800, 0x29003980, 0x6800ba84, 0x41041904, 0x00000800, 54 | 0x40000200, 0x00008004, 0x6000ba04, 0x20003800, 0x00008000, 0x00003000, 0x20000000, 0x00008200, 55 | 0x0904c380, 0x08004200, 0x01047100, 0x09006100, 0x08007080, 0x41001180, 0x09043180, 0x08004100, 56 | 0x09047180, 0x09007180, 0x20000000, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 57 | 0x01046980, 0x08047180, 0x29006900, 0x01040180, 0x29004900, 0x01041180, 0x00041180, 0x09042180, 58 | 0x08047080, 0x21000900, 0x09044000, 0x40041280, 0x01040080, 0x08044284, 0x48044084, 0x09044180, 59 | 0x00047180, 0x49044180, 0x40047180, 0x09003180, 0x20000900, 0x09044080, 0x00048280, 0x4804c080, 60 | 0x40008204, 0x09007080, 0x01008300, 0x01040180, 0x40000004, 0x09004100, 0x40008000, 0x01000000, 61 | 0x00000004, 0x21041000, 0x41041080, 0x01043000, 0x0900e000, 0x01049000, 0x20003200, 0x09006200, 62 | 0x20041080, 0x20000000, 0x00048800, 0x60000a00, 0x00040080, 0x28043000, 0x20041000, 0x09043000, 63 | 0x00041084, 0x08006200, 0x00041000, 0x41002000, 0x01041080, 0x09040000, 0x00048000, 0x48048000, 64 | 0x40008204, 0x09006800, 0x01009000, 0x01009104, 0x20000800, 0x41002300, 0x0000b200, 0x00000000, 65 | 0x00000000, 0x00003000, 0x01003000, 0x01003100, 0x00007384, 0x29003900, 0x4000b800, 0x0100b200, 66 | 0x40008000, 0x0800b800, 0x20000000, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 67 | 0x09043000, 0x00003000, 0x48041000, 0x28043000, 0x00001900, 0x00005280, 0x29002000, 0x00000180, 68 | 0x00007980, 0x00001980, 0x20000000, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 69 | 0x00000000, 0x08004000, 0x00004800, 0x29007800, 0x29003980, 0x6800ba84, 0x41041904, 0x00000800, 70 | 0x40000200, 0x00008004, 0x6000ba04, 0x20003800, 0x00008000, 0x00003000, 0x20000000, 0x00008200, 71 | 0x09045180, 0x21000800, 0x01007100, 0x09005100, 0x08007080, 0x09003100, 0x09043100, 0x08004100, 72 | 0x09047180, 0x01007180, 0x20000800, 0x00008800, 0x40001200, 0x01003000, 0x0000a004, 0x20006100, 73 | 0x01046980, 0x40041280, 0x01042180, 0x08004880, 0x00009300, 0x0804e280, 0x21041a00, 0x00001380, 74 | 0x01001100, 0x08004200, 0x09005200, 0x00007100, 0x48004000, 0x0100a000, 0x40048000, 0x4100a000, 75 | 0x09041000, 0x01044180, 0x00008300, 0x49004004, 0x00000a04, 0x09044280, 0x20000204, 0x00007180, 76 | 0x41008000, 0x48000804, 0x0900a000, 0x01040180, 0x40000004, 0x09004100, 0x40008000, 0x01000000, 77 | 0x00000004, 0x40041280, 0x01042180, 0x08004880, 0x00009300, 0x0804e280, 0x21041a00, 0x00001380, 78 | 0x01001100, 0x08004200, 0x09005200, 0x00007100, 0x48004000, 0x0100a000, 0x40048000, 0x4100a000, 79 | 0x09041000, 0x01044180, 0x00008300, 0x49004004, 0x00000a04, 0x09044280, 0x20000204, 0x00007180, 80 | 0x41008000, 0x48000804, 0x0900a000, 0x01009104, 0x20000800, 0x41002300, 0x0000b200, 0x00000000, 81 | }; 82 | 83 | const uint8_t asciiOnOff[] = { 84 | 0x05, 0x02, 0x03, 0x04, 0x07, 0x07, 0x05, 0x05, 85 | 0x02, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 86 | 0x05, 0x02, 0x04, 0x06, 0x04, 0x06, 0x03, 0x04, 87 | 0x05, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 88 | 0x00, 0x02, 0x02, 0x07, 0x08, 0x0a, 0x07, 0x01, 89 | 0x02, 0x02, 0x08, 0x04, 0x01, 0x02, 0x01, 0x02, 90 | 0x08, 0x03, 0x06, 0x05, 0x05, 0x05, 0x07, 0x03, 91 | 0x08, 0x07, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 92 | 0x07, 0x07, 0x07, 0x04, 0x06, 0x05, 0x04, 0x06, 93 | 0x06, 0x04, 0x04, 0x05, 0x03, 0x06, 0x06, 0x06, 94 | 0x06, 0x07, 0x07, 0x06, 0x03, 0x05, 0x04, 0x06, 95 | 0x04, 0x06, 0x04, 0x04, 0x02, 0x04, 0x02, 0x01, 96 | 0x01, 0x04, 0x05, 0x04, 0x05, 0x04, 0x04, 0x05, 97 | 0x04, 0x01, 0x03, 0x04, 0x02, 0x05, 0x03, 0x05, 98 | 0x04, 0x04, 0x02, 0x03, 0x04, 0x03, 0x02, 0x04, 99 | 0x04, 0x05, 0x03, 0x05, 0x02, 0x05, 0x04, 0x00, 100 | 0x00, 0x02, 0x03, 0x04, 0x07, 0x07, 0x05, 0x05, 101 | 0x02, 0x05, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 102 | 0x05, 0x02, 0x04, 0x05, 0x03, 0x04, 0x04, 0x02, 103 | 0x06, 0x04, 0x01, 0x02, 0x03, 0x03, 0x03, 0x04, 104 | 0x00, 0x02, 0x02, 0x07, 0x08, 0x0a, 0x07, 0x01, 105 | 0x02, 0x02, 0x08, 0x04, 0x01, 0x02, 0x01, 0x02, 106 | 0x07, 0x03, 0x05, 0x05, 0x05, 0x05, 0x06, 0x03, 107 | 0x08, 0x06, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 108 | 0x07, 0x05, 0x05, 0x04, 0x04, 0x07, 0x06, 0x04, 109 | 0x03, 0x03, 0x05, 0x04, 0x03, 0x03, 0x03, 0x04, 110 | 0x04, 0x05, 0x03, 0x05, 0x03, 0x06, 0x03, 0x05, 111 | 0x03, 0x04, 0x04, 0x04, 0x02, 0x04, 0x02, 0x01, 112 | 0x01, 0x05, 0x05, 0x04, 0x04, 0x07, 0x06, 0x04, 113 | 0x03, 0x03, 0x05, 0x04, 0x03, 0x03, 0x03, 0x04, 114 | 0x04, 0x05, 0x03, 0x05, 0x03, 0x06, 0x03, 0x05, 115 | 0x03, 0x04, 0x04, 0x05, 0x02, 0x05, 0x04, 0x00, 116 | }; 117 | 118 | const uint32_t segment_mask_c = 0x96230e7a; 119 | const uint32_t spin_mask_c[] = { 120 | 0x00000040, 0x04000040, 0x06000040, 0x06200040, 121 | 0x06210040, 0x06230040, 0x06230042, 0x06230052, 122 | 0x06230452, 0x86230452, 0x96230452, 0x96230472, 123 | 0x9623047a, 0x9623067a, 0x96230e7a, }; 124 | const uint32_t asciiA_c[] = { 125 | 0x02210012, 0x00000012, 0x00200012, 0x00200052, 0x14020452, 0x8220005a, 0x80000232, 0x80200212, 126 | 0x00000220, 0x82000212, 0x00000008, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000058, 127 | 0x04020052, 0x80000008, 0x86000008, 0x86030008, 0x10000620, 0x02200650, 0x80000012, 0x80200012, 128 | 0x80200052, 0x10000660, 0x00000008, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000058, 129 | 0x00000000, 0x06000000, 0x84000000, 0x8620001a, 0x8222005a, 0x9202063a, 0x80210462, 0x80000000, 130 | 0x10000020, 0x00000600, 0x9000063a, 0x8000001a, 0x00000200, 0x00000012, 0x00000008, 0x10000200, 131 | 0x16230240, 0x16000000, 0x04210052, 0x06200050, 0x06020012, 0x00220062, 0x02230052, 0x06000040, 132 | 0x06230052, 0x06220052, 0x00000008, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000058, 133 | 0x84230050, 0x06030052, 0x86200058, 0x00230040, 0x86200048, 0x00230042, 0x00030042, 0x02230050, 134 | 0x06030012, 0x80200048, 0x06210000, 0x10030022, 0x00230000, 0x16030400, 0x06030420, 0x06230040, 135 | 0x04030052, 0x06230060, 0x04030072, 0x02220052, 0x80000048, 0x06230000, 0x10030200, 0x06030220, 136 | 0x10000620, 0x06220012, 0x10200240, 0x00230040, 0x00000420, 0x06200040, 0x00000220, 0x00200000, 137 | 0x00000400, 0x0021000a, 0x00230022, 0x00210012, 0x06200210, 0x00210202, 0x1000001a, 0x16200010, 138 | 0x0003000a, 0x00000008, 0x80010200, 0x90000028, 0x00030000, 0x0201001a, 0x0001000a, 0x02210012, 139 | 0x00030402, 0x16000010, 0x00010002, 0x00200030, 0x00230002, 0x02210000, 0x00010200, 0x02010220, 140 | 0x10000620, 0x86200010, 0x00200202, 0x00200642, 0x80000008, 0x10200070, 0x10000212, 0x00000000, 141 | 0x00000000, 0x00000012, 0x00200012, 0x00200052, 0x14020452, 0x8220005a, 0x80000232, 0x10200212, 142 | 0x00000220, 0x82000212, 0x00000008, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000058, 143 | 0x02210012, 0x00000012, 0x02010022, 0x0201001a, 0x80000042, 0x14020002, 0x02200018, 0x00020040, 144 | 0x84020052, 0x80020042, 0x00000008, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000058, 145 | 0x00000000, 0x06000000, 0x84000000, 0x8620001a, 0x8222005a, 0x9202063a, 0x80210462, 0x80000000, 146 | 0x10000020, 0x00000600, 0x9000063a, 0x8000001a, 0x00000200, 0x00000012, 0x00000008, 0x10000200, 147 | 0x06230042, 0x80200008, 0x04200052, 0x06200042, 0x06020012, 0x02200052, 0x02210052, 0x06000040, 148 | 0x06230052, 0x04220052, 0x80000008, 0x80000200, 0x10000022, 0x00200012, 0x00000610, 0x04000058, 149 | 0x84230050, 0x10030022, 0x00230050, 0x86020000, 0x10000242, 0x16030210, 0x9021000a, 0x10020042, 150 | 0x00200042, 0x16000000, 0x16200002, 0x04000052, 0x06000020, 0x00200210, 0x00010220, 0x00200230, 151 | 0x02210002, 0x04230040, 0x10000240, 0x06200420, 0x90000400, 0x16230000, 0x10000408, 0x04020052, 152 | 0x00200220, 0x82000420, 0x02200210, 0x00230040, 0x00000420, 0x06200040, 0x00000220, 0x00200000, 153 | 0x00000400, 0x10030022, 0x00230050, 0x86020000, 0x10000242, 0x16030210, 0x9021000a, 0x10020042, 154 | 0x00200042, 0x16000000, 0x16200002, 0x04000052, 0x06000020, 0x00200210, 0x00010220, 0x00200230, 155 | 0x02210002, 0x04230040, 0x10000240, 0x06200420, 0x90000400, 0x16230000, 0x10000408, 0x04020052, 156 | 0x00200220, 0x82000420, 0x02200210, 0x00200642, 0x80000008, 0x10200070, 0x10000212, 0x00000000, 157 | }; 158 | 159 | const uint32_t asciiB_c[] = { 160 | 0x04020052, 0x00000012, 0x00000052, 0x00200052, 0x02210232, 0x8022005a, 0x1000041a, 0x1000005a, 161 | 0x10000400, 0x1002001a, 0x80000000, 0x10000008, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 162 | 0x02210012, 0x80000008, 0x80030008, 0x86030008, 0x10000620, 0x10220062, 0x0000001a, 0x0000005a, 163 | 0x0020005a, 0x10200620, 0x80000000, 0x10000008, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 164 | 0x00000000, 0x00030000, 0x00010008, 0x8003005a, 0x8222005a, 0x9202063a, 0x04200478, 0x00000008, 165 | 0x00000600, 0x10000020, 0x9000063a, 0x8000001a, 0x10000000, 0x00000012, 0x80000000, 0x10000200, 166 | 0x16230240, 0x00030200, 0x04210052, 0x00230042, 0x02030012, 0x02200450, 0x06220052, 0x00230000, 167 | 0x06230052, 0x02230052, 0x80000000, 0x10000008, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 168 | 0x0621004a, 0x06230012, 0x8023004a, 0x06200040, 0x80230048, 0x06200050, 0x06200010, 0x06220042, 169 | 0x06030012, 0x80200048, 0x04030040, 0x06000610, 0x06000040, 0x06030220, 0x06030420, 0x06230040, 170 | 0x06210012, 0x06230440, 0x06210412, 0x02220052, 0x80200008, 0x06030040, 0x16000200, 0x16030400, 171 | 0x10000620, 0x02030052, 0x10200240, 0x06200040, 0x00000420, 0x00230040, 0x10000400, 0x00000040, 172 | 0x00000020, 0x84000050, 0x06000450, 0x04000052, 0x10030042, 0x14000050, 0x80000212, 0x00030242, 173 | 0x86000010, 0x80000000, 0x14000008, 0x80000608, 0x06000000, 0x84020012, 0x84000010, 0x04020052, 174 | 0x06000030, 0x00030202, 0x04000010, 0x00000442, 0x06000050, 0x04020040, 0x14000000, 0x14020400, 175 | 0x10000620, 0x0003004a, 0x10000050, 0x10200070, 0x80000008, 0x00200642, 0x10000212, 0x00000000, 176 | 0x00000000, 0x00000012, 0x00000052, 0x00200052, 0x02210232, 0x8022005a, 0x1000041a, 0x10000252, 177 | 0x10000400, 0x1002001a, 0x80000000, 0x10000008, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 178 | 0x04020052, 0x00000012, 0x04020410, 0x84020012, 0x00200018, 0x02010210, 0x80020042, 0x02200000, 179 | 0x0221001a, 0x02200018, 0x80000000, 0x10000008, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 180 | 0x00000000, 0x00030000, 0x00010008, 0x8003005a, 0x8222005a, 0x9202063a, 0x04200478, 0x00000008, 181 | 0x00000600, 0x10000020, 0x9000063a, 0x8000001a, 0x10000000, 0x00000012, 0x80000000, 0x10000200, 182 | 0x06230050, 0x80000048, 0x00210052, 0x00230050, 0x02030012, 0x00220052, 0x04220052, 0x00230000, 183 | 0x06230052, 0x02210052, 0x80000008, 0x10000008, 0x00000610, 0x00000052, 0x10000022, 0x80210002, 184 | 0x0621004a, 0x06000610, 0x06200042, 0x02030008, 0x10200210, 0x16030202, 0x84000258, 0x02200210, 185 | 0x00200050, 0x00030200, 0x00030250, 0x00210012, 0x00030400, 0x10000042, 0x14000400, 0x10000442, 186 | 0x04020050, 0x06210040, 0x10200200, 0x00030460, 0x00000228, 0x06030240, 0x80000220, 0x02210012, 187 | 0x10000440, 0x00020428, 0x10020042, 0x06200040, 0x00000420, 0x00230040, 0x10000400, 0x00000040, 188 | 0x00000020, 0x06000610, 0x06200042, 0x02030008, 0x10200210, 0x16030202, 0x84000258, 0x02200210, 189 | 0x00200050, 0x00030200, 0x00030250, 0x00210012, 0x00030400, 0x10000042, 0x14000400, 0x10000442, 190 | 0x04020050, 0x06210040, 0x10200200, 0x00030460, 0x00000228, 0x06030240, 0x80000220, 0x02210012, 191 | 0x10000440, 0x00020428, 0x10020042, 0x10200070, 0x80000008, 0x00200642, 0x10000212, 0x00000000, 192 | }; 193 | 194 | -------------------------------------------------------------------------------- /s14clock_firmware/zf.pl: -------------------------------------------------------------------------------- 1 | #!/bin/perl -w 2 | use strict; 3 | 4 | # ___ a 5 | # f|\|/|b (hjk) 6 | # - - g G 7 | # e|/|\|c (nml) 8 | # === d 9 | # ___ 10 | # |\|/| 11 | # - - 12 | # |/|\| 13 | # ___ 14 | # 15 | my $not_used =<<'_E'; 16 | a , d , 17 | fhjkb , clmne , 18 | g G , G g , 19 | enmlc , bkjhf , 20 | d , a , 21 | 22 | ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , 23 | |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , 24 | - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , 25 | |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , 26 | ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , 27 | 28 | , , , , ___ , , ___ , , , , , , , , , , 29 | , | , | | , | | , | | , |\|/ , \| , | , / , \ , \|/ , | , , , , / , 30 | , , , - - , - - , - - , - , , , , - - , - - , , - - , , , 31 | , | , , | | , | | , /|\| , | \ , , \ , / , /|\ , | , / , , | , / , 32 | , , , ___ , ___ , , ___ , , , , , , , , , , 33 | original numerics 34 | ___ , , ___ , ___ , , ___ , ___ , ___ , ___ , ___ , , , , , , ___ , 35 | | /| , /| , | , | , | | , | , | , | , | | , | | , , | , / , , \ , | , 36 | , , - - , - , - - , - , - - , , - - , - - , , , - , - - , - , - , 37 | |/ | , | , | , | , | , \ , | | , | , | | , | , | , / , \ , , / , | , 38 | ___ , , ___ , ___ , , ___ , ___ , , ___ , ___ , , , , ___ , , , 39 | # 0x00 chinese numerics attempt 40 | , , , ___ , ___ , ___ , , , , , , , , , , ___ , 41 | , , , , |\ /| , | , | , | , , | , , | , / , , \ , | , 42 | - - , - - , - - , - - , - - , - - , - - , - - , , - - , , , - , - - , - , - , 43 | | | , , , , , | | , / \ , / , / \ , / | , | , / , \ , , / , | , 44 | ___ , , ___ , ___ , , ___ , , ___ , , , , , , ___ , , , 45 | # 0x10 chinese "scratch/flower" code attempt 46 | ___ , , , , , ___ , , , ___ , ___ , , , , , , ___ , 47 | | | , | , | | , | | | , \ / , \ , | , | , | , \ / , , | , / , , \ , | , 48 | - - , , , , , - , - - , - - , - - , , , , - , - - , - , - , 49 | , | , | | , | | | , / \ , / | , , , , / \ , | , / , \ , , / , | , 50 | , , , , , ___ , , ___ , ___ , , , , , ___ , , , 51 | # 0x80 vertical numerics attempt 52 | , , , , ___ , , , ___ , , ___ , , , , , , ___ , 53 | , , , , | , | /| , , | , , | | , , | , / , , \ , | , 54 | - - , - - , - , - - , - , - , - , , - - , - , , , - , - - , - , - , 55 | | | , , | \| , | | | , , , | | , , | | | , , | , / , \ , , / , | , 56 | ___ , , , , , , ___ , , ___ , , , , , ___ , , , 57 | _E 58 | 59 | my $orig =<<'_END'; 60 | # 0x00 chinese numerics attempt 61 | , , , ___ , ___ , ___ , , , , , , , , , , ___ , 62 | , , , , |\ /| , | , | , | , , | , , | , / , , \ , | , 63 | - - , - - , - - , - - , - - , - - , - - , - - , , - - , , , - , - - , - , - , 64 | | | , , , , , | | , / \ , / , / \ , / | , | , / , \ , , / , | , 65 | ___ , , ___ , ___ , , ___ , , ___ , , , , , , ___ , , , 66 | # 0x10 chinese "scratch/flower" code attempt 67 | ___ , , , , , ___ , , , ___ , ___ , , , , , , ___ , 68 | | | , | , | | , | | | , \ / , \ , | , | , | , \ / , , | , / , , \ , | , 69 | - - , , , , , - , - - , - - , - - , , , , - , - - , - , - , 70 | , | , | | , | | | , / \ , / | , , , , / \ , | , / , \ , , / , | , 71 | , , , , , ___ , , ___ , ___ , , , , , ___ , , , 72 | # 0x20 default set 73 | , , , , ___ , , ___ , , , , , , , , , , 74 | , | , | | , | | , | | , |\|/ , \| , | , / , \ , \|/ , | , , , , / , 75 | , , , - - , - - , - - , - , , , , - - , - - , , - - , , , 76 | , | , , | | , | | , /|\| , | \ , , \ , / , /|\ , | , / , , | , / , 77 | , , , ___ , ___ , , ___ , , , , , , , , , , 78 | ___ , , ___ , ___ , , ___ , ___ , ___ , ___ , ___ , , , , , , ___ , 79 | | /| , /| , | , | , | | , | , | , | , | | , | | , , | , / , , \ , | , 80 | , , - - , - , - - , - , - - , , - - , - - , , , - , - - , - , - , 81 | |/ | , | , | , | , | , \ , | | , | , | | , | , | , / , \ , , / , | , 82 | ___ , , ___ , ___ , , ___ , ___ , , ___ , ___ , , , , ___ , , , 83 | ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , , ___ , , , , , , ___ , 84 | | | | , | | , | | , | , | | , | , | , | , | | , | , | , | / , | , |\ /| , |\ | , | | , 85 | - , - - , - , , , - , - , - , - - , , , - , , , , , 86 | | , | | , | | , | , | | , | , | , | | , | | , | , | | , | \ , | , | | , | \| , | | , 87 | ___ , , ___ , ___ , ___ , ___ , , ___ , , ___ , ___ , , ___ , , , ___ , 88 | ___ , ___ , ___ , ___ , ___ , , , , , , ___ , ___ , , ___ , , , 89 | | | , | | , | | , | , | , | | , | / , | | , \ / , | | , / , | , \ , | , , , 90 | - - , , - - , - - , , , , , , - - , , , , , , , 91 | | , | \| , | \ , | , | , | | , |/ , |/ \| , / \ , | , / , | , \ , | , / \ , , 92 | , ___ , , ___ , , ___ , , , , ___ , ___ , ___ , , ___ , , ___ , 93 | , , , , , , , , , , , , , , , , 94 | \ , , | , , | , , / , /| , | , , | , |/ , | , , , , 95 | , - , - , - - , - , - , - - , - , - , , , , , - - , - , - - , 96 | , | | , | \ , | , / | , |/ , | , | , | | , | , |/ , |\ , | , | | | , | | , | | , 97 | , ___ , ___ , ___ , ___ , ___ , , ___ , , , , , , , , ___ , 98 | , , , , , , , , , , , ___ , , ___ , , , 99 | |\ , /| , , , | , , , , \ / , | | , , \ , | , / , / , , 100 | - , - , - , - , - , , , , , - , - , - , , - , - - , , 101 | | , | , | , \ , | , | | , |/ , |/ \| , / \ , | , / , / , | , \ , / , , 102 | , , , ___ , ___ , ___ , , , , ___ , ___ , ___ , , ___ , , , 103 | # 0x80 chinese numerics attempt 104 | , , , ___ , ___ , ___ , , , , , , , , , , ___ , 105 | , , , , |\ /| , | , | , / , , | , , | , / , , \ , | , 106 | , - - , - - , - - , - - , - - , - - , - - , , - - , , , - , - - , - , - , 107 | , , , , , | | , / \ , / , / \ , / | , | , / , \ , , / , | , 108 | , , ___ , ___ , , ___ , , ___ , , , , , , ___ , , , 109 | # 0x90 vertical numerics attempt 110 | , , , , ___ , , , ___ , ___ , ___ , , , , , , ___ , 111 | , , , , | , | /| , , | , | | | , | | , , | , / , , \ , | , 112 | - - , - - , - , - - , - , - , - , , - - , - , , , - , - - , - , - , 113 | | | , , | \| , | | | , , , | | , , , , | , / , \ , , / , | , 114 | ___ , , , , , , ___ , , , , , , , ___ , , , 115 | # 0xa0 aurebesh (starwars) alphabet set 116 | , , , , ___ , , ___ , , , , , , , , , , 117 | , | , | | , | | , | | , |\|/ , \| , | , / , \ , \|/ , | , , , , / , 118 | , , , - - , - - , - - , - , , , , - - , - - , , - - , , , 119 | , | , , | | , | | , /|\| , | \ , , \ , / , /|\ , | , / , , | , / , 120 | , , , ___ , ___ , , ___ , , , , , , , , , , 121 | ___ , , ___ , ___ , , ___ , ___ , ___ , ___ , ___ , , , , , , ___ , 122 | | | , | , | , | , | | , , , | , | | , | | , | , | , / , , \ , | , 123 | - , , - - , - , - - , - - , - - , , - - , - - , , , - , - - , - , - , 124 | | | , | , , | , | , | , | | , | , | | , , | , / , \ , , / , | , 125 | ___ , ___ , ___ , ___ , , ___ , ___ , , ___ , ___ , , , , ___ , , , 126 | ___ , , ___ , , ___ , , , ___ , ___ , , , ___ , , , , , 127 | | | | , | / , | , | | | , / , | /| , |/ , | / , , /| , /| , | , | , , , , 128 | - , - , - , , - , - , - , - , - , , - , - - , , - , , - , 129 | | , | \ , | , | , / , |/ | , | | , , , | , | , , \| , / , |/ \ , / | , 130 | ___ , , ___ , , , , ___ , , ___ , , ___ , , , ___ , , ___ , 131 | , ___ , ___ , , , , , ___ , , , , ___ , , ___ , , , 132 | , | | , / , \ | , \|/ , | /| , \ / , | | , , \| , , | , \ , | , , , 133 | - , , , , , , , - - , , , - , , , , , , 134 | | | , | , / , \| , , | | , | , , / \ , \| , / | , | , \ , | , / \ , , 135 | ___ , ___ , , ___ , , ___ , , , ___ , , ___ , ___ , , ___ , , ___ , 136 | , , ___ , , ___ , , , ___ , ___ , , , ___ , , , , , 137 | \ , | / , | , | | | , / , | /| , |/ , | / , , /| , /| , | , | , , , , 138 | , - , - , , - , - , - , - , - , , - , - - , , - , , - , 139 | , | \ , | , | , / , |/ | , | | , , , | , | , , \| , / , |/ \ , / | , 140 | , , ___ , , , , ___ , , ___ , , ___ , , , ___ , , ___ , 141 | , ___ , ___ , , , , , ___ , , , , ___ , , ___ , , , 142 | , | | , / , \ | , \|/ , | /| , \ / , | | , , \| , , \ , | , / , / , , 143 | - , , , , , , , - - , , , - , - , , - , - - , , 144 | | | , | , / , \| , , | | , | , , / \ , \| , / | , / , | , \ , / , , 145 | ___ , ___ , , ___ , , ___ , , , ___ , , ___ , ___ , , ___ , , , 146 | 147 | _END 148 | 149 | # aurebesh (starwars) alphabet 150 | 151 | sub gen_file { my ($fn, $dg, $sg) = @_; 152 | 153 | open O, ">$fn.h" or die "cannot create file $fn.h\n"; 154 | my @use_dg = @{$dg}; 155 | $fn =~ /3/ and @use_dg = (@{$dg}[0..11], @{$sg}[0..11]); 156 | 157 | print O "const uint8_t digit_map[] = { ", join ", ", @use_dg, " };\n"; 158 | print O "const uint8_t digit_map_r[] = { ", join ", ", reverse(@use_dg), " };\n\n"; 159 | 160 | if ($fn =~ m/2l/) { # l means long bar, v2l use 74HC154, v3l use charliplexing 161 | print O "#define ENABLE_154 15\n"; 162 | print O "#define NUM_OF_DIGITS 24\n"; 163 | } 164 | else { 165 | printf O "#define NUM_OF_DIGITS %d\n", $#use_dg+1; 166 | } 167 | 168 | my ($repeat, $suf) = (1, ""); 169 | $fn =~ /3/ and do { 170 | print O "#define CHARLIE 12\n"; 171 | $repeat++; 172 | }; 173 | 174 | while ($repeat) { 175 | my $mask = 0; 176 | my @spin_mask = (); 177 | my $bit16=1; 178 | for my $b (@{$sg}) { 179 | $mask |= 1<<$b; 180 | $b > 15 and $bit16=0; 181 | push @spin_mask, $mask; 182 | } 183 | 184 | #$bit16 and printf O "#define BIT16_SEG 1\n"; 185 | printf O "const uint32_t segment_mask$suf = 0x%08x;\n", (($mask >> 32)<<23) | ($mask&0x00ffffff); 186 | #printf O "const uint32_t segment_maskA$suf = 0x%08x;\n", $mask & 0xffffffff; 187 | #printf O "const uint32_t segment_maskB$suf = 0x%08x;\n", $mask >> 32; 188 | 189 | for my $b (@{$dg}) { 190 | $mask |= 1<<$b; 191 | } 192 | $suf or do { 193 | printf O "const uint32_t all_mask = 0x%08x;\n", (($mask >> 32)<<23) | ($mask&0x00ffffff); 194 | #printf O "const uint32_t all_maskA = 0x%08x;\n", $mask & 0xffffffff; 195 | #printf O "const uint32_t all_maskB = 0x%08x;\n", $mask >> 32; 196 | }; 197 | print O "const uint32_t spin_mask${suf}[] = {\n"; 198 | my $cnt=0; 199 | for (@spin_mask) { 200 | printf O "0x%08x, ", (($_ >> 32)<<23) | ($_&0x00ffffff); 201 | ++$cnt % 4 or print O "\n"; 202 | } 203 | print O "};\n"; 204 | 205 | =pod 206 | print O "const uint32_t spin_maskA${suf}[] = {\n"; 207 | $cnt=0; 208 | for (@spin_mask) { 209 | printf O "0x%08x, ", $_ & 0xffffffff; 210 | ++$cnt % 4 or print O "\n"; 211 | } 212 | print O "};\n"; 213 | 214 | print O "const uint32_t spin_maskB${suf}[] = {\n"; 215 | $cnt=0; 216 | for (@spin_mask) { 217 | printf O "0x%08x, ", $_ >> 32; 218 | ++$cnt % 4 or print O "\n"; 219 | } 220 | print O "};\n"; 221 | =cut 222 | 223 | 224 | my @brightness = (); 225 | 226 | my ($a0, $a1, $a2) = ( 227 | "const uint32_t asciiA${suf}[] = {\n", 228 | "const uint32_t asciiB${suf}[] = {\n", 229 | "const uint8_t asciiOnOff${suf}[] = {\n",); 230 | 231 | #for my $raw ($orig, $full) { 232 | for my $raw ($orig) { 233 | my $c = 0; 234 | my @row = (); 235 | my $m = "abcdefgGhjklmn"; 236 | my $m0 = " a fhjkb g G enmlc d "; 237 | my $m1 = " d clmne G g bkjhf a "; 238 | for (split('\n', $raw)) { 239 | /,/ or next; 240 | $c or @row = (); 241 | my @col = split ',', $_; 242 | @col = map(substr($_, 1, 5), @col); 243 | my $i = 0; 244 | for my $e (@col) { 245 | $row[$i++] .= $e; 246 | } 247 | ++$c == 5 and do { 248 | #print O "($row[1])\n"; 249 | for my $i (0..15) { 250 | my @seg = split '', $row[$i]; 251 | my ($a, $b, $c, $cn) = (0, 0, 0, 0); 252 | for (split '', $m) { 253 | #$seg[index($m0, $_)] ne ' ' and $a |= $cmp; 254 | #$seg[index($m1, $_)] ne ' ' and $b |= $cmp; 255 | #$cmp <<= 1; 256 | $seg[index($m0, $_)] ne ' ' and do { $a |= 1<<$sg->[$c]; $cn++; }; 257 | $seg[index($m1, $_)] ne ' ' and $b |= 1<<$sg->[$c]; 258 | $c++; 259 | } 260 | push @brightness, $cn; 261 | #$a0 .= sprintf O "0x%04x, ", $a; 262 | #$a1 .= sprintf O "0x%04x, ", $b; 263 | $a0 .= sprintf "0x%08x, ", ($a & 0xffffff) | (($a >> 33) << 24); 264 | $a1 .= sprintf "0x%08x, ", ($b & 0xffffff) | (($b >> 33) << 24); 265 | $i == 7 and do { 266 | $a0 .= "\n"; 267 | $a1 .= "\n"; 268 | }; 269 | } 270 | $a0 .= "\n"; 271 | $a1 .= "\n"; 272 | $c = 0; 273 | }; 274 | } 275 | $a0 .= "};\n\n"; 276 | $a1 .= "};\n\n"; 277 | print O $a0, $a1; 278 | 279 | $suf or do { 280 | print O $a2; 281 | for (@brightness) { 282 | printf O "0x%02x, ", $_; 283 | ++$c & 0x7 or print O "\n"; 284 | } 285 | print O "};\n\n"; 286 | }; 287 | 288 | } 289 | $repeat--; 290 | ($sg, $dg) = ($dg, $sg); 291 | $suf = "_c"; 292 | } 293 | close O; 294 | } 295 | 296 | #my @digits = ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ); # ver1 297 | #my @digits = ( 10, 12, 13, 14, 16, 8, 11, 35, 38, 37, 40, 39, ); # ver2 298 | #my @digits = ( 34, 16, 17, 18, 21, 33, 36, 35, 37, 38, 39, 40, ); # ver2l 299 | #my @p = ( 13, 14, 15, 16, 17, 18, 21, 33, 34, 35, 36, 39, 38, 37, 38, ); # ver1 300 | #my @p = ( 17, 21, 1, 3, 2, 18, 5, 4, 34, 33, 36, 9, 6, 7, 15, ); # ver2 301 | #my @p = ( 11, 13, 1, 5, 2, 14, 3, 4, 8, 9, 10, 12, 6, 7, 6, ); # ver2l 302 | 303 | gen_file("ver1", 304 | [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,], # digits 1-12 305 | [ 13, 14, 15, 16, 17, 18, 21, 33, 34, 35, 36, 39, 38, 37, 38,]); # segments 0-14 306 | 307 | gen_file("ver2", 308 | [ 10, 12, 13, 14, 16, 8, 11, 35, 38, 37, 40, 39,], 309 | [ 17, 21, 1, 3, 2, 18, 5, 4, 34, 33, 36, 7, 6, 9, 15,]); # segment S11 and S13 switched in schematic 310 | 311 | gen_file("ver2l", 312 | [ 34, 16, 17, 18, 21, 33, 36, 35, 37, 38, 39, 40,], 313 | [ 11, 13, 1, 5, 2, 14, 3, 4, 8, 9, 10, 7, 6, 12, 6,]); 314 | 315 | #gen_file("ver3", 316 | # [ 34, 16, 17, 18, 21, 33, 36, 35, 38, 37, 40, 39,], 317 | # [ 11, 13, 1, 5, 2, 14, 3, 4, 8, 9, 10, 12, 6, 7, 15,]); 318 | 319 | gen_file("ver3", 320 | #[ 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 5, 3, 9, 11,], 321 | #[ 33, 18, 7, 8, 14, 36, 13, 12, 39, 38, 15, 2, 11, 9, 11,] 322 | [ 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 5, 3, 9, 11,], 323 | [ 33, 18, 7, 8, 14, 36, 13, 12, 39, 38, 15, 2, 11, 9, 11,] 324 | #[ 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 5, ], 325 | #[ 33, 18, 7, 8, 14, 36, 13, 12, 39, 38, 15, 9, 11, 2, 11,] 326 | #[ 33, 18, 7, 8, 14, 36, 13, 12, 39, 38, 15, 2,], 327 | #[ 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 9, 3, 5, 11,] 328 | # a, b, c, d, e, f, g, G, h, i, j, k, l, m, n, 329 | ); 330 | 331 | 332 | -------------------------------------------------------------------------------- /s14clock_firmware/zf1.pl: -------------------------------------------------------------------------------- 1 | #!/bin/perl -w 2 | use strict; 3 | use feature 'state'; 4 | 5 | # ___ a 6 | # f|\|/|b (hjk) 7 | # - - g G 8 | # e|/|\|c (nml) 9 | # === d 10 | # ___ 11 | # |\|/| 12 | # - - 13 | # |/|\| 14 | # ___ 15 | # 16 | my $not_used =<<'_E'; 17 | a , d , 18 | fhjkb , clmne , 19 | g G , G g , 20 | enmlc , bkjhf , 21 | d , a , 22 | 23 | ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , 24 | |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , |\|/| , 25 | - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , - - , 26 | |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , |/|\| , 27 | ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , 28 | 29 | , , , , ___ , , ___ , , , , , , , , , , 30 | , | , | | , | | , | | , |\|/ , \| , | , / , \ , \|/ , | , , , , / , 31 | , , , - - , - - , - - , - , , , , - - , - - , , - - , , , 32 | , | , , | | , | | , /|\| , | \ , , \ , / , /|\ , | , / , , | , / , 33 | , , , ___ , ___ , , ___ , , , , , , , , , , 34 | original numerics 35 | ___ , , ___ , ___ , , ___ , ___ , ___ , ___ , ___ , , , , , , ___ , 36 | | /| , /| , | , | , | | , | , | , | , | | , | | , , | , / , , \ , | , 37 | , , - - , - , - - , - , - - , , - - , - - , , , - , - - , - , - , 38 | |/ | , | , | , | , | , \ , | | , | , | | , | , | , / , \ , , / , | , 39 | ___ , , ___ , ___ , , ___ , ___ , , ___ , ___ , , , , ___ , , , 40 | # 0x00 chinese numerics attempt 41 | , , , ___ , ___ , ___ , , , , , , , , , , ___ , 42 | , , , , |\ /| , | , | , | , , | , , | , / , , \ , | , 43 | - - , - - , - - , - - , - - , - - , - - , - - , , - - , , , - , - - , - , - , 44 | | | , , , , , | | , / \ , / , / \ , / | , | , / , \ , , / , | , 45 | ___ , , ___ , ___ , , ___ , , ___ , , , , , , ___ , , , 46 | # 0x10 chinese "scratch/flower" code attempt 47 | ___ , , , , , ___ , , , ___ , ___ , , , , , , ___ , 48 | | | , | , | | , | | | , \ / , \ , | , | , | , \ / , , | , / , , \ , | , 49 | - - , , , , , - , - - , - - , - - , , , , - , - - , - , - , 50 | , | , | | , | | | , / \ , / | , , , , / \ , | , / , \ , , / , | , 51 | , , , , , ___ , , ___ , ___ , , , , , ___ , , , 52 | # 0x80 vertical numerics attempt 53 | , , , , ___ , , , ___ , , ___ , , , , , , ___ , 54 | , , , , | , | /| , , | , , | | , , | , / , , \ , | , 55 | - - , - - , - , - - , - , - , - , , - - , - , , , - , - - , - , - , 56 | | | , , | \| , | | | , , , | | , , | | | , , | , / , \ , , / , | , 57 | ___ , , , , , , ___ , , ___ , , , , , ___ , , , 58 | _E 59 | 60 | my $orig =<<'_END'; 61 | # 0x00 chinese numerics attempt 62 | , , , ___ , ___ , ___ , , , , , , , , , , ___ , 63 | , , , , |\ /| , | , | , | , , | , , | , / , , \ , | , 64 | - - , - - , - - , - - , - - , - - , - - , - - , , - - , , , - , - - , - , - , 65 | | | , , , , , | | , / \ , / , / \ , / | , | , / , \ , , / , | , 66 | ___ , , ___ , ___ , , ___ , , ___ , , , , , , ___ , , , 67 | # 0x10 chinese "scratch/flower" code attempt 68 | ___ , , , , , ___ , , , ___ , ___ , , , , , , ___ , 69 | | | , | , | | , | | | , \ / , \ , | , | , | , \ / , , | , / , , \ , | , 70 | - - , , , , , - , - - , - - , - - , , , , - , - - , - , - , 71 | , | , | | , | | | , / \ , / | , , , , / \ , | , / , \ , , / , | , 72 | , , , , , ___ , , ___ , ___ , , , , , ___ , , , 73 | # 0x20 default set 74 | , , , , ___ , , ___ , , , , , , , , , , 75 | , | , | | , | | , | | , |\|/ , \| , | , / , \ , \|/ , | , , , , / , 76 | , , , - - , - - , - - , - , , , , - - , - - , , - - , , , 77 | , | , , | | , | | , /|\| , | \ , , \ , / , /|\ , | , / , , | , / , 78 | , , , ___ , ___ , , ___ , , , , , , , , , , 79 | ___ , , ___ , ___ , , ___ , ___ , ___ , ___ , ___ , , , , , , ___ , 80 | | /| , /| , | , | , | | , | , | , | , | | , | | , , | , / , , \ , | , 81 | , , - - , - , - - , - , - - , , - - , - - , , , - , - - , - , - , 82 | |/ | , | , | , | , | , \ , | | , | , | | , | , | , / , \ , , / , | , 83 | ___ , , ___ , ___ , , ___ , ___ , , ___ , ___ , , , , ___ , , , 84 | ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , , ___ , , , , , , ___ , 85 | | | | , | | , | | , | , | | , | , | , | , | | , | , | , | / , | , |\ /| , |\ | , | | , 86 | - , - - , - , , , - , - , - , - - , , , - , , , , , 87 | | , | | , | | , | , | | , | , | , | | , | | , | , | | , | \ , | , | | , | \| , | | , 88 | ___ , , ___ , ___ , ___ , ___ , , ___ , , ___ , ___ , , ___ , , , ___ , 89 | ___ , ___ , ___ , ___ , ___ , , , , , , ___ , ___ , , ___ , , , 90 | | | , | | , | | , | , | , | | , | / , | | , \ / , | | , / , | , \ , | , , , 91 | - - , , - - , - - , , , , , , - - , , , , , , , 92 | | , | \| , | \ , | , | , | | , |/ , |/ \| , / \ , | , / , | , \ , | , / \ , , 93 | , ___ , , ___ , , ___ , , , , ___ , ___ , ___ , , ___ , , ___ , 94 | , , , , , , , , , , , , , , , , 95 | \ , , | , , | , , / , /| , | , , | , |/ , | , , , , 96 | , - , - , - - , - , - , - - , - , - , , , , , - - , - , - - , 97 | , | | , | \ , | , / | , |/ , | , | , | | , | , |/ , |\ , | , | | | , | | , | | , 98 | , ___ , ___ , ___ , ___ , ___ , , ___ , , , , , , , , ___ , 99 | , , , , , , , , , , , ___ , , ___ , , , 100 | |\ , /| , , , | , , , , \ / , | | , , \ , | , / , / , , 101 | - , - , - , - , - , , , , , - , - , - , , - , - - , , 102 | | , | , | , \ , | , | | , |/ , |/ \| , / \ , | , / , / , | , \ , / , , 103 | , , , ___ , ___ , ___ , , , , ___ , ___ , ___ , , ___ , , , 104 | # 0x80 chinese numerics attempt 105 | , , , ___ , ___ , ___ , , , , , , , , , , ___ , 106 | , , , , |\ /| , | , | , / , , | , , | , / , , \ , | , 107 | - - , - - , - - , - - , - - , - - , - - , - - , , - - , , , - , - - , - , - , 108 | | | , , , , , | | , / \ , / , / \ , / | , | , / , \ , , / , | , 109 | ___ , , ___ , ___ , , ___ , , ___ , , , , , , ___ , , , 110 | # 0x90 vertical numerics attempt 111 | , , , , ___ , , , ___ , ___ , ___ , , , , , , ___ , 112 | , , , , | , | /| , , | , | | | , | | , , | , / , , \ , | , 113 | - - , - - , - , - - , - , - , - , , - - , - , , , - , - - , - , - , 114 | | | , , | \| , | | | , , , | | , , , , | , / , \ , , / , | , 115 | ___ , , , , , , ___ , , , , , , , ___ , , , 116 | # 0xa0 aurebesh (starwars) alphabet set 117 | , , , , ___ , , ___ , , , , , , , , , , 118 | , | , | | , | | , | | , |\|/ , \| , | , / , \ , \|/ , | , , , , / , 119 | , , , - - , - - , - - , - , , , , - - , - - , , - - , , , 120 | , | , , | | , | | , /|\| , | \ , , \ , / , /|\ , | , / , , | , / , 121 | , , , ___ , ___ , , ___ , , , , , , , , , , 122 | ___ , , ___ , ___ , , ___ , ___ , ___ , ___ , ___ , , , , , , ___ , 123 | | | , | , | , | , | | , , , | , | | , | | , | , | , / , , \ , | , 124 | - , , - - , - , - - , - - , - - , , - - , - - , , , - , - - , - , - , 125 | | | , | , , | , | , | , | | , | , | | , , | , / , \ , , / , | , 126 | ___ , ___ , ___ , ___ , , ___ , ___ , , ___ , ___ , , , , ___ , , , 127 | ___ , , ___ , , ___ , , , ___ , ___ , , , ___ , , , , , 128 | | | | , | / , | , | | | , / , | /| , |/ , | / , , /| , /| , | , | , , , , 129 | - , - , - , , - , - , - , - , - , , - , - - , , - , , - , 130 | | , | \ , | , | , / , |/ | , | | , , , | , | , , \| , / , |/ \ , / | , 131 | ___ , , ___ , , , , ___ , , ___ , , ___ , , , ___ , , ___ , 132 | , ___ , ___ , , , , , ___ , , , , ___ , , ___ , , , 133 | , | | , / , \ | , \|/ , | /| , \ / , | | , , \| , , | , \ , | , , , 134 | - , , , , , , , - - , , , - , , , , , , 135 | | | , | , / , \| , , | | , | , , / \ , \| , / | , | , \ , | , / \ , , 136 | ___ , ___ , , ___ , , ___ , , , ___ , , ___ , ___ , , ___ , , ___ , 137 | , , ___ , , ___ , , , ___ , ___ , , , ___ , , , , , 138 | \ , | / , | , | | | , / , | /| , |/ , | / , , /| , /| , | , | , , , , 139 | , - , - , , - , - , - , - , - , , - , - - , , - , , - , 140 | , | \ , | , | , / , |/ | , | | , , , | , | , , \| , / , |/ \ , / | , 141 | , , ___ , , , , ___ , , ___ , , ___ , , , ___ , , ___ , 142 | , ___ , ___ , , , , , ___ , , , , ___ , , ___ , , , 143 | , | | , / , \ | , \|/ , | /| , \ / , | | , , \| , , \ , | , / , / , , 144 | - , , , , , , , - - , , , - , - , , - , - - , , 145 | | | , | , / , \| , , | | , | , , / \ , \| , / | , / , | , \ , / , , 146 | ___ , ___ , , ___ , , ___ , , , ___ , , ___ , ___ , , ___ , , , 147 | 148 | _END 149 | 150 | # aurebesh (starwars) alphabet 151 | 152 | sub gen_file { 153 | my ($fn, $dg, $sg) = @_; 154 | 155 | my @use_dg = @{$dg}; 156 | $fn =~ /3/ and @use_dg = (@{$dg}[0..11], @{$sg}[0..11]); 157 | # v3 led arranged as led1, led3, led2, led4 158 | #$fn =~ /3/ and @use_dg = (@{$dg}[0..5], @{$sg}[0..5], @{$dg}[6..11], @{$sg}[6..11]); 159 | 160 | print "const uint8_t digit_map_${fn}[] = { ", join ", ", @use_dg, " };\n"; 161 | print "const uint8_t digit_map_r_${fn}[] = { ", join ", ", reverse(@use_dg), " };\n\n"; 162 | 163 | #if ($fn =~ m/2l/) { # l means long bar, v2l use 74HC154, v3l use charliplexing 164 | # print "#define ENABLE_154 15\n"; 165 | # print "#define NUM_OF_DIGITS 24\n"; 166 | #} 167 | #else { 168 | # printf "#define NUM_OF_DIGITS %d\n", $#use_dg+1; 169 | #} 170 | 171 | my ($repeat, $suf) = (1, ""); 172 | $fn =~ /3/ and do { 173 | #print "#define CHARLIE 12\n"; 174 | $repeat++; 175 | }; 176 | 177 | while ($repeat) { 178 | my $mask = 0; 179 | my @spin_mask = (); 180 | my $bit16=1; 181 | for my $b (@{$sg}) { 182 | $mask |= 1<<$b; 183 | $b > 15 and $bit16=0; 184 | push @spin_mask, $mask; 185 | } 186 | 187 | #$bit16 and printf "#define BIT16_SEG 1\n"; 188 | printf "const uint32_t segment_mask_$fn$suf = 0x%08x;\n", (($mask >> 32)<<23) | ($mask&0x00ffffff); 189 | #printf "const uint32_t segment_maskA$suf = 0x%08x;\n", $mask & 0xffffffff; 190 | #printf "const uint32_t segment_maskB$suf = 0x%08x;\n", $mask >> 32; 191 | 192 | for my $b (@{$dg}) { 193 | $mask |= 1<<$b; 194 | } 195 | $suf or do { 196 | printf "const uint32_t all_mask_$fn = 0x%08x;\n", (($mask >> 32)<<23) | ($mask&0x00ffffff); 197 | #printf "const uint32_t all_maskA = 0x%08x;\n", $mask & 0xffffffff; 198 | #printf "const uint32_t all_maskB = 0x%08x;\n", $mask >> 32; 199 | }; 200 | print "const uint32_t spin_mask_$fn${suf}[] = {\n"; 201 | my $cnt=0; 202 | for (@spin_mask) { 203 | printf "0x%08x, ", (($_ >> 32)<<23) | ($_&0x00ffffff); 204 | ++$cnt % 4 or print "\n"; 205 | } 206 | print "};\n"; 207 | 208 | =pod 209 | print "const uint32_t spin_maskA${suf}[] = {\n"; 210 | $cnt=0; 211 | for (@spin_mask) { 212 | printf "0x%08x, ", $_ & 0xffffffff; 213 | ++$cnt % 4 or print "\n"; 214 | } 215 | print "};\n"; 216 | 217 | print "const uint32_t spin_maskB${suf}[] = {\n"; 218 | $cnt=0; 219 | for (@spin_mask) { 220 | printf "0x%08x, ", $_ >> 32; 221 | ++$cnt % 4 or print "\n"; 222 | } 223 | print "};\n"; 224 | =cut 225 | 226 | 227 | my @brightness = (); 228 | 229 | state $genOnOff = 0; 230 | 231 | my ($a0, $a1, $a2) = ( 232 | "const uint32_t asciiA_$fn${suf}[] = {\n", 233 | "const uint32_t asciiB_$fn${suf}[] = {\n", 234 | "const uint8_t asciiOnOff${suf}[] = {\n",); 235 | 236 | #for my $raw ($orig, $full) { 237 | for my $raw ($orig) { 238 | my $c = 0; 239 | my @row = (); 240 | my $m = "abcdefgGhjklmn"; 241 | my $m0 = " a fhjkb g G enmlc d "; 242 | my $m1 = " d clmne G g bkjhf a "; 243 | for (split('\n', $raw)) { 244 | /,/ or next; 245 | $c or @row = (); 246 | my @col = split ',', $_; 247 | @col = map(substr($_, 1, 5), @col); 248 | my $i = 0; 249 | for my $e (@col) { 250 | $row[$i++] .= $e; 251 | } 252 | ++$c == 5 and do { 253 | #print "($row[1])\n"; 254 | for my $i (0..15) { 255 | my @seg = split '', $row[$i]; 256 | my ($a, $b, $c, $cn) = (0, 0, 0, 0); 257 | for (split '', $m) { 258 | #$seg[index($m0, $_)] ne ' ' and $a |= $cmp; 259 | #$seg[index($m1, $_)] ne ' ' and $b |= $cmp; 260 | #$cmp <<= 1; 261 | $seg[index($m0, $_)] ne ' ' and do { $a |= 1<<$sg->[$c]; $cn++; }; 262 | $seg[index($m1, $_)] ne ' ' and $b |= 1<<$sg->[$c]; 263 | $c++; 264 | } 265 | push @brightness, $cn; 266 | #$a0 .= sprintf "0x%04x, ", $a; 267 | #$a1 .= sprintf "0x%04x, ", $b; 268 | $a0 .= sprintf "0x%08x, ", ($a & 0xffffff) | (($a >> 33) << 24); 269 | $a1 .= sprintf "0x%08x, ", ($b & 0xffffff) | (($b >> 33) << 24); 270 | $i == 7 and do { 271 | $a0 .= "\n"; 272 | $a1 .= "\n"; 273 | }; 274 | } 275 | $a0 .= "\n"; 276 | $a1 .= "\n"; 277 | $c = 0; 278 | }; 279 | } 280 | $a0 .= "};\n\n"; 281 | $a1 .= "};\n\n"; 282 | print $a0, $a1; 283 | 284 | #$suf or do { 285 | $genOnOff or do { 286 | print $a2; 287 | for (@brightness) { 288 | printf "0x%02x, ", $_; 289 | ++$c & 0x7 or print "\n"; 290 | } 291 | print "};\n\n"; 292 | }; 293 | $genOnOff++; 294 | 295 | } 296 | $repeat--; 297 | ($sg, $dg) = ($dg, $sg); 298 | $suf = "_c"; 299 | } 300 | } 301 | 302 | #my @digits = ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ); # ver1 303 | #my @digits = ( 10, 12, 13, 14, 16, 8, 11, 35, 38, 37, 40, 39, ); # ver2 304 | #my @digits = ( 34, 16, 17, 18, 21, 33, 36, 35, 37, 38, 39, 40, ); # ver2l 305 | #my @p = ( 13, 14, 15, 16, 17, 18, 21, 33, 34, 35, 36, 39, 38, 37, 38, ); # ver1 306 | #my @p = ( 17, 21, 1, 3, 2, 18, 5, 4, 34, 33, 36, 9, 6, 7, 15, ); # ver2 307 | #my @p = ( 11, 13, 1, 5, 2, 14, 3, 4, 8, 9, 10, 12, 6, 7, 6, ); # ver2l 308 | 309 | #gen_file("v1", 310 | # [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,], # digits 1-12 311 | # [ 13, 14, 15, 16, 17, 18, 21, 33, 34, 35, 36, 39, 38, 37, 38,]); # segments 0-14 312 | gen_file("v2", 313 | [ 10, 12, 13, 14, 16, 8, 11, 35, 38, 37, 40, 39,], 314 | [ 17, 21, 1, 3, 2, 18, 5, 4, 34, 33, 36, 7, 6, 9, 15,]); # segment S11 and S13 switched in schematic 315 | 316 | gen_file("v2l", 317 | [ 34, 16, 17, 18, 21, 33, 36, 35, 37, 38, 39, 40,], 318 | [ 11, 13, 1, 5, 2, 14, 3, 4, 8, 9, 10, 7, 6, 12, 6,]); 319 | 320 | #gen_file("ver3", 321 | # [ 34, 16, 17, 18, 21, 33, 36, 35, 38, 37, 40, 39,], 322 | # [ 11, 13, 1, 5, 2, 14, 3, 4, 8, 9, 10, 12, 6, 7, 15,]); 323 | 324 | gen_file("v3", 325 | #[ 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 5, 3, 9, 11,], 326 | #[ 33, 18, 7, 8, 14, 36, 13, 12, 39, 38, 15, 2, 11, 9, 11,] 327 | [ 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 5, 11, 9, 9, ], 328 | [ 33, 3, 7, 8, 14, 36, 13, 12, 39, 38, 15, 2, 11, 9, 9, ] 329 | #[ 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 5, ], 330 | #[ 33, 18, 7, 8, 14, 36, 13, 12, 39, 38, 15, 9, 11, 2, 11,] 331 | #[ 33, 18, 7, 8, 14, 36, 13, 12, 39, 38, 15, 2,], 332 | #[ 6, 35, 34, 21, 16, 17, 1, 4, 10, 40, 37, 9, 3, 5, 11,] 333 | # a, b, c, d, e, f, g, G, h, i, j, k, l, m, n, 334 | ); 335 | 336 | 337 | -------------------------------------------------------------------------------- /zgen.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | 5 | 6 | open I, "websource" or die; 7 | 8 | my (@tag, $ltag, $etag) = ((), "", ""); 9 | 10 | print <<_HEADER; 11 | 12 | 13 | 14 | _HEADER 15 | 16 | my $old=<<_OLD; 17 | 31 | _OLD 32 | 33 | my $skipped = 0; 34 | 35 | while () { 36 | chomp; 37 | /^#/ and next; 38 | /^:v\s+(\w+)/ and do { 39 | print <<_YOUTUBE; 40 | 41 |

42 | _YOUTUBE 43 | next; 44 | }; 45 | /^:j(\d*)\s+([\w\-\.]+)\s?([\w\-\.]*)\s?([\w\-\.]*)/ and do { 46 | #print "
"; 47 | my ($width, $img1, $img2, $img3, $class) = ($1, $2, $3, $4, ""); 48 | $width and $class = "class=\"w$width\""; 49 | print "
"; 50 | $img2 and print ""; 51 | $img3 and print ""; 52 | print "

\n"; 53 | next; 54 | }; 55 | 56 | /^:(\w+)$/ and do { 57 | push @tag, $1; 58 | print "<$1>\n"; 59 | $1 eq 'ul' and ($ltag, $etag) = ("li", ""); 60 | next; 61 | }; 62 | /^:(\w+)\s+(.+)$/ and do { 63 | print "<$1>$2
\n"; 64 | next; 65 | }; 66 | /^:$/ and do { 67 | while (@tag) { 68 | printf "\n", pop @tag; 69 | } 70 | ($ltag, $etag) = ("", ""); 71 | next; 72 | }; 73 | /^([\s\t])*$/ and do { 74 | $skipped or print "
\n"; 75 | $skipped = 1; 76 | next; 77 | }; 78 | $skipped = 0; 79 | length $_ < 20 && $#tag == 1 and do { 80 | print "$_
\n"; 81 | next; 82 | }; 83 | s/l\((.+);([^\)]+)\)/$1<\/a>/g; 84 | s/([bs])\(([^\)]+)\)/<$1>$2<\/$1>/g; 85 | if ($ltag) { 86 | $ltag and print "<$ltag>$_\n"; 87 | } 88 | else { 89 | if (m//|| $#tag > 0) { 90 | print "$_\n"; 91 | } 92 | else { 93 | print "

$_

\n"; 94 | } 95 | } 96 | } 97 | 98 | close I; 99 | 100 | print "\n"; 101 | 102 | --------------------------------------------------------------------------------