├── SDKdemo.pgm ├── lib └── gcc111libbid_hard.a ├── _layouts ├── asciidoc.html ├── page.html ├── default.html ├── docu.html ├── post.html ├── home.html └── dirlisting.html ├── _includes ├── footer.html ├── header.html ├── custom-head.html └── head.html ├── antora.yml ├── bin ├── check_qspi_crc └── add_pgm_chsum ├── readme_build.md ├── dmcp ├── startup_pgm.s ├── qrcode.h ├── sys │ ├── sdb.h │ └── pgm_syscalls.c ├── ff_ifc.h ├── lft_ifc.h └── dmcp.h ├── readme.md ├── index.md ├── readme.adoc ├── LICENSE ├── src ├── qspi_crc.h ├── main.h ├── menu.h ├── num.h ├── menu.c └── main.c ├── Makefile ├── stm32_program.ld └── help └── sdkdemo.html /SDKdemo.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swissmicros/SDKdemo/HEAD/SDKdemo.pgm -------------------------------------------------------------------------------- /lib/gcc111libbid_hard.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swissmicros/SDKdemo/HEAD/lib/gcc111libbid_hard.a -------------------------------------------------------------------------------- /_layouts/asciidoc.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docu 3 | --- 4 |
5 | {{ content }} 6 |
7 | 8 | -------------------------------------------------------------------------------- /_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 |
5 | {{ content }} 6 |
7 | 8 | -------------------------------------------------------------------------------- /_includes/footer.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /antora.yml: -------------------------------------------------------------------------------- 1 | name: SDKdemo 2 | title: SDK Demo 3 | version: master 4 | asciidoc: 5 | attributes: 6 | source-language: asciidoc@ 7 | table-caption: false 8 | nav: 9 | - modules/contribute/nav.adoc 10 | -------------------------------------------------------------------------------- /_includes/header.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {%- include head.html -%} 5 | 6 | 7 | 8 | {%- include header.html -%} 9 |
10 |
11 | {{ content }} 12 |
13 |
14 | 15 | {%- include footer.html -%} 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /_layouts/docu.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {%- include head.html -%} 5 | 6 | 7 | 8 | {%- include header.html -%} 9 |
10 |
11 | {{ content }} 12 |
13 |
14 | 15 | {%- include footer.html -%} 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /bin/check_qspi_crc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pgm=$1 4 | h=${2:-dm/qspi_crc.h} 5 | 6 | q=build/${pgm}_qspi.bin 7 | 8 | 9 | filesize() { 10 | stat -Lc%s "$1" 11 | } 12 | 13 | 14 | if [ ! -f "$q" ];then 15 | echo "ERROR: Missing qspi file '$q'" 16 | exit 1 17 | fi 18 | 19 | if [ ! -f "$h" ]; then 20 | sz=0 21 | crc=0 22 | else 23 | sz=`cat $h | grep SIZE | awk '{print $3}'` 24 | crc=`cat $h | grep CRC | awk '{print $3}'` 25 | fi 26 | 27 | nsz=`filesize $q` 28 | ncrc=0x`crc32 $q` 29 | 30 | if [ $sz != $nsz -o $crc != $ncrc ]; then 31 | cat << OI 32 | ==== 33 | QSPI Contents changed: 34 | Size: $sz -> $nsz 35 | CRC: $crc -> $ncrc 36 | ==== 37 | Run build once more. 38 | OI 39 | cat << OI > $h 40 | 41 | #define QSPI_DATA_SIZE $nsz 42 | #define QSPI_DATA_CRC $ncrc 43 | 44 | OI 45 | exit 1 46 | fi 47 | -------------------------------------------------------------------------------- /_includes/custom-head.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Placeholder to allow defining custom head, in principle, you can add anything here, e.g. favicons: 3 | 4 | 1. Head over to https://realfavicongenerator.net/ to add your own favicons. 5 | 2. Customize default _includes/custom-head.html in your source directory and insert the given code snippet. 6 | {% endcomment %} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {{ page.path }} 18 | 19 | -------------------------------------------------------------------------------- /readme_build.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docu 3 | --- 4 | 5 | ## Prerequisites 6 | 7 | GNU ARM toolchain can be downloaded from 8 | https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads. 9 | We are currently using Version 7-2018-q2-update Linux 64-bit. 10 | 11 | Make is usually available in some base development package, but you 12 | can install it directly, e.g. for debian like systems 13 | sudo apt-get install make 14 | 15 | Basic shell utilities (usually present in system): 16 | bash, dd, sed, tac, printf, find, etc. 17 | 18 | Some usually available aux utilities (could require separate installation): 19 | crc32, sha1sum 20 | 21 | 22 | 23 | ## Build 24 | 25 | Add ARM toolchain bin/ directory to PATH. 26 | ``` 27 | (e.g. ~/arm/gcc-arm-none-eabi-7-2018-q2-update/bin) 28 | ``` 29 | Run make to build the program. 30 | 31 | Generated program 32 | build/SDKdemo.pgm 33 | 34 | Contents of QSPI 35 | build/SDKdemo_qspi.bin 36 | 37 | 38 | 39 | ## SDKdemo repository 40 | 41 | The latest version of SDKdemo is available at 42 | [https://github.com/swissmicros/SDKdemo](https://github.com/swissmicros/SDKdemo)) 43 | 44 | 45 | 46 | 47 | ## SDKdemo help file 48 | 49 | You can copy the help/sdkdemo.html file to directory /HELP/ on calculator filesystem. 50 | Then the help is available directly on calculator by pressing F1 key. 51 | 52 | -------------------------------------------------------------------------------- /bin/add_pgm_chsum: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | bin=$1 4 | pgm=$2 5 | 6 | # -- Functions ------------ 7 | 8 | 9 | checkutils() { 10 | e=0 11 | for p in "$@"; do 12 | type $p > /dev/null 2>&1 13 | if [ $? != 0 ]; then 14 | e=1 15 | echo "ERROR: Missing required utility $p" 16 | fi 17 | done 18 | if [ $e != 0 ]; then 19 | exit 1 20 | fi 21 | } 22 | 23 | 24 | # Convert hex digits to uint32_t 25 | toint() { 26 | local x 27 | x=`printf "%08x" "0x$1" | 28 | sed -e 's|\(..\)|\1@|g' | tr '@' '\012' | tac | tr -d '\012' | 29 | sed -e 's|\(..\)|@\1|g' | sed -e 's|@|\\\x|g'` 30 | printf "$x" 31 | } 32 | 33 | toint8() { 34 | local x 35 | x=`printf "$1" | sed -e 's|\(..\)|@\1|g' | sed -e 's|@|\\\x|g'` 36 | printf "$x" 37 | } 38 | 39 | dumppgm() { 40 | ( 41 | dd if=$bin bs=4 count=1 42 | toint $hexsz 43 | dd if=$bin bs=4 skip=2 44 | ) 2>/dev/null 45 | } 46 | 47 | 48 | 49 | # -- MAIN ------------------ 50 | 51 | checkutils sha1sum sed tac dd printf find type 52 | 53 | if [ ! -f "$bin" ]; then 54 | echo "ERROR: Cannot find program binary '$bin'" 55 | exit 1 56 | fi 57 | 58 | if [ -z "$pgm" ]; then 59 | echo "ERROR: Missing destination file name" 60 | exit 1 61 | fi 62 | 63 | pgmsz=`find "$bin" -printf "%s"` 64 | hexsz=`printf "%08x" $pgmsz` 65 | 66 | sha=`dumppgm | sha1sum | tr -d ' -'` 67 | 68 | echo "SHA1: $sha" 69 | 70 | ( 71 | dumppgm 72 | toint8 $sha 73 | ) > $pgm 74 | 75 | 76 | -------------------------------------------------------------------------------- /_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 |
5 | 6 |
7 |

{{ page.title | escape }}

8 | 27 |
28 | 29 |
30 | {{ content }} 31 |
32 | 33 | {%- if site.disqus.shortname -%} 34 | {%- include disqus_comments.html -%} 35 | {%- endif -%} 36 | 37 | 38 |
39 | -------------------------------------------------------------------------------- /dmcp/startup_pgm.s: -------------------------------------------------------------------------------- 1 | /** 2 | */ 3 | 4 | .syntax unified 5 | .cpu cortex-m4 6 | .fpu softvfp 7 | .thumb 8 | 9 | 10 | /* == Following section addresses are defined in ld script == */ 11 | 12 | /* = initialized data should be copied from flash to RAM before pgm start = */ 13 | /* .data section start addr in flash */ 14 | .word _sidata 15 | /* .data section start addr in RAM */ 16 | .word _sdata 17 | /* .data section end addr in RAM */ 18 | .word _edata 19 | 20 | /* = .bss section should be zeroed before pgm start = */ 21 | /* .bss section start addr in RAM */ 22 | .word _sbss 23 | /* .bss section end addr */ 24 | .word _ebss 25 | 26 | /** **/ 27 | 28 | 29 | /** 30 | Program entry point 31 | */ 32 | 33 | .section .text.Program_Entry 34 | .weak Program_Entry 35 | .type Program_Entry, %function 36 | Program_Entry: 37 | 38 | /* Copy the data segment initializers from flash to SRAM */ 39 | ldr r0, =_sidata 40 | ldr r1, =_sdata 41 | ldr r2, =_edata 42 | b CopyDataInit0 43 | 44 | CopyDataInit: 45 | ldr r3, [r0], #4 46 | str r3, [r1], #4 47 | CopyDataInit0: 48 | cmp r1, r2 49 | bcc CopyDataInit 50 | 51 | /* Zero fill the bss segment. */ 52 | movs r0, #0 53 | ldr r1, =_sbss 54 | ldr r2, = _ebss 55 | b FillZerobss0 56 | 57 | FillZerobss: 58 | str r0, [r1], #4 59 | FillZerobss0: 60 | cmp r1, r2 61 | bcc FillZerobss 62 | 63 | 64 | /* Call static constructors */ 65 | bl __libc_init_array 66 | /* Call the application entry point.*/ 67 | bl program_main 68 | bl post_main 69 | 70 | /* Just for sure as post_main shouldn't return. */ 71 | LoopForever: 72 | b LoopForever 73 | 74 | .size Program_Entry, .-Program_Entry 75 | 76 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docu 3 | --- 4 | 5 | # SDKdemo 6 | 7 | [https://tech.swissmicros.com/SDKdemo/](https://tech.swissmicros.com/SDKdemo/) 8 | 9 | ## This repo contains the sources for SDK demo project - simple scientific RPN calculator 10 | 11 | - There is DMCP interface doc in progress see [DMCP IFC doc](http://technical.swissmicros.com/dmcp/doc/DMCP-ifc-html/) 12 | (or you can download html zip from [doc directory](http://technical.swissmicros.com/dmcp/doc/)). 13 | 14 | 15 | README file contains basic instructions how to prepare building environment and build the program. 16 | 17 | For the basic SDK with simple 'Hello World!' program look at DMCP_SDK repository. 18 | 19 | You can look at this SDKdemo project for more advanced project with 20 | keyboard handling, more sophisticated LCD printing, power management, build with Intel® Decimal 21 | Floating-Point Math Library, user defined menus and more. 22 | 23 | For ultimate project which uses other aspect of the DMCP system (like system timers, bitmap printing 24 | to LCD or printing to IR printer) look at sources of the DM42PGM project. 25 | 26 | At this time the only source of information about the use of DMCP system interface is based on 27 | the source code of DMCP programs. 28 | 29 | ## The SDK and related material is released as “NOMAS” (NOt MAnufacturer Supported). 30 | 31 | 1. Info is released to assist customers using, exploring and extending the product 32 | 33 | 1. Do NOT contact the manufacturer with questions, seeking support, etc. regarding NOMAS material as no support is implied or committed-to by the Manufacturer 34 | 35 | 1. The Manufacturer may reply and/or update materials if and when needed solely at their discretion 36 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docu 3 | --- 4 | 5 | # SDKdemo 6 | 7 | [https://github.com/swissmicros/SDKdemo](https://github.com/swissmicros/SDKdemo) 8 | 9 | [readme_build.html](readme_build.html) 10 | 11 | ## This repo contains the sources for SDK demo project - simple scientific RPN calculator 12 | 13 | - There is DMCP interface doc in progress see [DMCP IFC doc](http://technical.swissmicros.com/dmcp/doc/DMCP-ifc-html/) 14 | (or you can download html zip from [doc directory](http://technical.swissmicros.com/dmcp/doc/)). 15 | 16 | 17 | README file contains basic instructions how to prepare building environment and build the program. 18 | 19 | For the basic SDK with simple 'Hello World!' program look at DMCP_SDK repository. 20 | 21 | You can look at this SDKdemo project for more advanced project with 22 | keyboard handling, more sophisticated LCD printing, power management, build with Intel® Decimal 23 | Floating-Point Math Library, user defined menus and more. 24 | 25 | For ultimate project which uses other aspect of the DMCP system (like system timers, bitmap printing 26 | to LCD or printing to IR printer) look at sources of the DM42PGM project. 27 | 28 | At this time the only source of information about the use of DMCP system interface is based on 29 | the source code of DMCP programs. 30 | 31 | ## The SDK and related material is released as “NOMAS” (NOt MAnufacturer Supported). 32 | 33 | 1. Info is released to assist customers using, exploring and extending the product 34 | 35 | 1. Do NOT contact the manufacturer with questions, seeking support, etc. regarding NOMAS material as no support is implied or committed-to by the Manufacturer 36 | 37 | 1. The Manufacturer may reply and/or update materials if and when needed solely at their discretion 38 | -------------------------------------------------------------------------------- /readme.adoc: -------------------------------------------------------------------------------- 1 | ''''' 2 | 3 | == layout: docu 4 | 5 | == SDKdemo 6 | 7 | https://tech.swissmicros.com/SDKdemo/[https://tech.swissmicros.com/SDKdemo/] 8 | 9 | === This repo contains the sources for SDK demo project - simple scientific RPN calculator 10 | 11 | * There is DMCP interface doc in progress see 12 | http://technical.swissmicros.com/dmcp/doc/DMCP-ifc-html/[DMCP IFC doc] 13 | (or you can download html zip from 14 | http://technical.swissmicros.com/dmcp/doc/[doc directory]). 15 | 16 | README file contains basic instructions how to prepare building 17 | environment and build the program. 18 | 19 | For the basic SDK with simple 'Hello World!' program look at DMCP_SDK 20 | repository. 21 | 22 | You can look at this SDKdemo project for more advanced project with 23 | keyboard handling, more sophisticated LCD printing, power management, 24 | build with Intel® Decimal Floating-Point Math Library, user defined 25 | menus and more. 26 | 27 | For ultimate project which uses other aspect of the DMCP system (like 28 | system timers, bitmap printing to LCD or printing to IR printer) look at 29 | sources of the DM42PGM project. 30 | 31 | At this time the only source of information about the use of DMCP system 32 | interface is based on the source code of DMCP programs. 33 | 34 | [[the-sdk-and-related-material-is-released-as-nomas-not-manufacturer-supported]] 35 | === The SDK and related material is released as “NOMAS” (NOt MAnufacturer Supported). 36 | 37 | . Info is released to assist customers using, exploring and extending 38 | the product 39 | . Do NOT contact the manufacturer with questions, seeking support, etc. 40 | regarding NOMAS material as no support is implied or committed-to by the 41 | Manufacturer 42 | . The Manufacturer may reply and/or update materials if and when needed 43 | solely at their discretion 44 | -------------------------------------------------------------------------------- /_layouts/home.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 | {%- if page.title -%} 7 |

{{ page.title }}

8 | {%- endif -%} 9 | 10 | {{ content }} 11 | 12 | 13 | {% if site.paginate %} 14 | {% assign posts = paginator.posts %} 15 | {% else %} 16 | {% assign posts = site.posts %} 17 | {% endif %} 18 | 19 | 20 | {%- if posts.size > 0 -%} 21 | {%- if page.list_title -%} 22 |

{{ page.list_title }}

23 | {%- endif -%} 24 | 40 | 41 | {% if site.paginate %} 42 |
43 | 56 |
57 | {%- endif %} 58 | 59 | {%- endif -%} 60 | 61 |
62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | -------------------------------------------------------------------------------- /src/qspi_crc.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | 44 | #define QSPI_DATA_SIZE 1370864 45 | #define QSPI_DATA_CRC 0x000cfed6 46 | 47 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __PGM_MAIN_H__ 44 | #define __PGM_MAIN_H__ 45 | 46 | #define PROGRAM_NAME "SDKdemo" 47 | #define PROGRAM_VERSION "1.0" 48 | 49 | #define DBG_PRINT 50 | 51 | #ifdef DBG_PRINT 52 | #include 53 | #else 54 | #define printf(...) 55 | #define puts(...) 56 | #endif 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __MENU_H__ 44 | #define __MENU_H__ 45 | 46 | // -------------------------------- 47 | // Menu items 48 | // app range 0-127 49 | // sys range 128-255 50 | // -------------------------------- 51 | 52 | #define MI_SETTINGS 10 53 | #define MI_ABOUT_PGM 11 54 | 55 | extern const smenu_t MID_MENU; 56 | 57 | 58 | // Menu callbacks 59 | int run_menu_item(uint8_t line_id); 60 | const char * menu_line_str(uint8_t line_id, char * s, const int slen); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /dmcp/qrcode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * This library is written and maintained by Richard Moore. 5 | * Major parts were derived from Project Nayuki's library. 6 | * 7 | * Copyright (c) 2017 Richard Moore (https://github.com/ricmoo/QRCode) 8 | * Copyright (c) 2017 Project Nayuki (https://www.nayuki.io/page/qr-code-generator-library) 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy 11 | * of this software and associated documentation files (the "Software"), to deal 12 | * in the Software without restriction, including without limitation the rights 13 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | * copies of the Software, and to permit persons to whom the Software is 15 | * furnished to do so, subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in 18 | * all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | * THE SOFTWARE. 27 | */ 28 | 29 | /** 30 | * Special thanks to Nayuki (https://www.nayuki.io/) from which this library was 31 | * heavily inspired and compared against. 32 | * 33 | * See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp 34 | */ 35 | 36 | #ifndef __QRCODE_H_ 37 | #define __QRCODE_H_ 38 | 39 | #ifndef __cplusplus 40 | typedef unsigned char bool; 41 | static const bool false = 0; 42 | static const bool true = 1; 43 | #endif 44 | 45 | #include 46 | 47 | 48 | // QR Code Format Encoding 49 | #define MODE_NUMERIC 0 50 | #define MODE_ALPHANUMERIC 1 51 | #define MODE_BYTE 2 52 | 53 | 54 | // Error Correction Code Levels 55 | #define ECC_LOW 0 56 | #define ECC_MEDIUM 1 57 | #define ECC_QUARTILE 2 58 | #define ECC_HIGH 3 59 | 60 | 61 | // If set to non-zero, this library can ONLY produce QR codes at that version 62 | // This saves a lot of dynamic memory, as the codeword tables are skipped 63 | #ifndef LOCK_VERSION 64 | #define LOCK_VERSION 0 65 | #endif 66 | 67 | 68 | typedef struct QRCode { 69 | uint8_t version; 70 | uint8_t size; 71 | uint8_t ecc; 72 | uint8_t mode; 73 | uint8_t mask; 74 | uint8_t *modules; 75 | } QRCode; 76 | 77 | 78 | #ifdef __cplusplus 79 | extern "C"{ 80 | #endif /* __cplusplus */ 81 | 82 | 83 | 84 | uint16_t qrcode_getBufferSize(uint8_t version); 85 | 86 | int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data); 87 | int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length); 88 | 89 | bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y); 90 | 91 | 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif /* __cplusplus */ 96 | 97 | 98 | #endif /* __QRCODE_H_ */ 99 | -------------------------------------------------------------------------------- /_layouts/dirlisting.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docu 3 | --- 4 | {% assign abs_url = page.url | absolute_url %} 5 | {% assign rel_url = page.url | relative_url %} 6 | {% if rel_url != '/' %} {% assign base_url = abs_url | replace: rel_url, '' | append: '/' %} 7 | {% else %} {% assign base_url = abs_url %} 8 | {% endif %} 9 | {% assign depth = page.path | split: '/' | size %} 10 | {% assign pwd = page.path | replace: page.name, '' %} 11 | 12 | 23 | 24 |

Directory listing {{ site.github.repository_name }}{{ page.url | replace page.path, '' | replace '/', '' }}

25 | 26 |
27 | {{ content }} 28 |
29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | {% capture folders_list %} 37 | {% for file in site.static_files %} 38 | {% assign path = file.path | split: '/' %} 39 | {% if path | size != depth %} 40 | {% if path[depth] != file.name %} 41 | {% assign dif = file.path | split: pwd %} 42 | {% if dif[0] == '/' || depth == 1 %} 43 | {{ file.path | replace: file.name, '' }} 44 | {% if forloop.last == false %}::{% endif%} 45 | {% endif %} 46 | {% endif %} 47 | {% endif %} 48 | {% endfor %} 49 | {% endcapture %} 50 | {% assign folders = folders_list | strip_newlines | replace: ' ', '' | split: '::'| uniq | sort %} 51 | 52 | 53 | {% capture top_folder_list %} 54 | {% for folder in folders %} 55 | {% assign path = folder | split: '/' %} 56 | {{ path[depth] }} 57 | {% if forloop.last == false %}::{% endif %} 58 | {% endfor %} 59 | {% endcapture %} 60 | {% assign top_folders = top_folder_list | strip_newlines | replace: ' ', '' | split: '::' | uniq | compact | sort %} 61 | 62 | 63 | 64 | 65 | 66 | {% if depth != 1 %} 67 | 68 | {% endif %} 69 | 70 | {% for folder in top_folders %} 71 | 72 | {% endfor %} 73 | 74 | {% for file in site.static_files %} 75 | {% assign path_s = file.path | split: '/' | size | minus: 1 %} 76 | {% if path_s == depth %} 77 | {% assign dif = file.path | split: pwd %} 78 | {% if dif[0] == '/' %} 79 | {% assign desc = page.descriptions | where:"name", file.name | first %} 80 | 81 | {% endif %} 82 | {% endif %} 83 | {% endfor %} 84 | 85 | 86 |
NameDescription
Parent Directory
{{ folder }}
{{ file.name }}{{ desc.text }}
87 | -------------------------------------------------------------------------------- /src/num.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __NUM_H__ 44 | #define __NUM_H__ 45 | 46 | /* 47 | ▄▄ ▄ 48 | █▀▄ █ ▄ ▄ ▄▄▄▄▄ 49 | █ █▄ █ █ █ █ █ █ 50 | █ █ █ █ █ █ █ █ 51 | █ ██ ▀▄▄▀█ █ █ █ 52 | 53 | */ 54 | 55 | 56 | #include 57 | #include 58 | 59 | typedef BID_UINT128 num_t; 60 | 61 | #define NUM_MAX_MANTISSA_DIGITS 34 62 | 63 | #define num_to_string bid128_to_string 64 | #define num_from_int32 bid128_from_int32 65 | 66 | #define num_to_string bid128_to_string 67 | #define num_from_string bid128_from_string 68 | 69 | #define num_to_int bid128_to_int32_int 70 | 71 | #define num_add bid128_add 72 | #define num_sub bid128_sub 73 | #define num_mul bid128_mul 74 | #define num_div bid128_div 75 | 76 | #define num_abs bid128_abs 77 | #define num_pow bid128_pow 78 | #define num_exp bid128_exp 79 | #define num_exp10 bid128_exp10 80 | #define num_sqrt bid128_sqrt 81 | #define num_log bid128_log 82 | #define num_log10 bid128_log10 83 | #define num_sin bid128_sin 84 | #define num_cos bid128_cos 85 | #define num_tan bid128_tan 86 | #define num_asin bid128_asin 87 | #define num_acos bid128_acos 88 | #define num_atan bid128_atan 89 | 90 | #define num_gt bid128_quiet_greater 91 | #define num_eq bid128_quiet_equal 92 | #define num_lt bid128_quiet_less 93 | #define num_le bid128_quiet_less_equal 94 | #define num_ne bid128_quiet_not_equal 95 | #define num_ge bid128_quiet_greater_equal 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /dmcp/sys/sdb.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2019, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __SYS_SDB_H__ 44 | #define __SYS_SDB_H__ 45 | 46 | // === IFC START === 47 | // System data block 48 | 49 | typedef int get_flag_fn_t(); 50 | typedef void set_flag_fn_t(int val); 51 | 52 | typedef int run_menu_item_fn_t(uint8_t line_id); 53 | typedef const char * menu_line_str_fn_t(uint8_t line_id, char * s, const int slen); 54 | 55 | typedef void void_fn_t(); 56 | 57 | 58 | typedef struct { 59 | volatile uint32_t calc_state; 60 | FIL * ppgm_fp; 61 | const char * key_to_alpha_table; 62 | 63 | run_menu_item_fn_t * run_menu_item_app; 64 | menu_line_str_fn_t * menu_line_str_app; 65 | 66 | void_fn_t * after_fat_format; 67 | 68 | get_flag_fn_t * is_flag_dmy; 69 | set_flag_fn_t * set_flag_dmy; 70 | get_flag_fn_t * is_flag_clk24; 71 | set_flag_fn_t * set_flag_clk24; 72 | get_flag_fn_t * is_beep_mute; 73 | set_flag_fn_t * set_beep_mute; 74 | 75 | disp_stat_t * pds_t20; 76 | disp_stat_t * pds_t24; 77 | disp_stat_t * pds_fReg; 78 | 79 | } sys_sdb_t; 80 | 81 | 82 | #define calc_state (sdb.calc_state) 83 | #define ppgm_fp (sdb.ppgm_fp) 84 | 85 | #define key_to_alpha_table (sdb.key_to_alpha_table) 86 | 87 | #define run_menu_item_app (sdb.run_menu_item_app) 88 | #define menu_line_str_app (sdb.menu_line_str_app) 89 | 90 | #define after_fat_format (sdb.after_fat_format) 91 | 92 | #define is_flag_dmy (sdb.is_flag_dmy) 93 | #define set_flag_dmy (sdb.set_flag_dmy) 94 | #define is_flag_clk24 (sdb.is_flag_clk24) 95 | #define set_flag_clk24 (sdb.set_flag_clk24) 96 | #define is_beep_mute (sdb.is_beep_mute) 97 | #define set_beep_mute (sdb.set_beep_mute) 98 | 99 | // === IFC END === 100 | 101 | 102 | extern sys_sdb_t sdb; 103 | 104 | #if 0 105 | // === IFC START === 106 | 107 | #define t20 (sdb.pds_t20) 108 | #define t24 (sdb.pds_t24) 109 | #define fReg (sdb.pds_fReg) 110 | 111 | #define sdb (*((sys_sdb_t*)0x10002000)) 112 | 113 | // === IFC END === 114 | #endif 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /src/menu.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #include 44 | #include 45 | 46 | #include 47 | 48 | 49 | const uint8_t mid_menu[] = { 50 | MI_SETTINGS, 51 | MI_MSC, 52 | MI_SYSTEM_ENTER, 53 | MI_ABOUT_PGM, 54 | 0 }; // Terminator 55 | 56 | 57 | const uint8_t mid_settings[] = { 58 | MI_SET_TIME, 59 | MI_SET_DATE, 60 | MI_BEEP_MUTE, 61 | MI_SLOW_AUTOREP, 62 | 0 }; // Terminator 63 | 64 | 65 | const smenu_t MID_MENU = { "Setup", mid_menu, NULL, NULL }; 66 | const smenu_t MID_SETTINGS = { "Settings", mid_settings, NULL, NULL}; 67 | 68 | 69 | 70 | 71 | void disp_about() { 72 | lcd_clear_buf(); 73 | lcd_writeClr(t24); 74 | 75 | // Just base of original system about 76 | lcd_for_calc(DISP_ABOUT); 77 | lcd_putsAt(t24,4,""); 78 | lcd_prevLn(t24); 79 | // -- 80 | 81 | int h2 = lcd_lineHeight(t20)/2; 82 | lcd_setXY(t20, t24->x, t24->y); 83 | t20->y += h2; 84 | lcd_print(t20, "SDKdemo v" PROGRAM_VERSION " (C) SwissMicros GmbH"); 85 | t20->y += h2; 86 | t20->y += h2; 87 | lcd_puts(t20, "Intel Decimal Floating-Point Math Lib v2.0"); 88 | lcd_puts(t20, " (C) 2007-2011, Intel Corp."); 89 | 90 | t20->y = LCD_Y - lcd_lineHeight(t20); 91 | lcd_putsR(t20, " Press EXIT key to continue..."); 92 | 93 | lcd_refresh(); 94 | 95 | wait_for_key_press(); 96 | } 97 | 98 | 99 | 100 | int run_menu_item(uint8_t line_id) { 101 | int ret = 0; 102 | 103 | switch(line_id) { 104 | case MI_ABOUT_PGM: 105 | disp_about(); 106 | break; 107 | 108 | case MI_SETTINGS: 109 | ret = handle_menu(&MID_SETTINGS,MENU_ADD, 0); 110 | break; 111 | 112 | default: 113 | ret = MRET_UNIMPL; 114 | break; 115 | } 116 | 117 | return ret; 118 | } 119 | 120 | 121 | const char * menu_line_str(uint8_t line_id, char * s, const int slen) { 122 | const char * ln; 123 | 124 | switch(line_id) { 125 | 126 | case MI_SETTINGS: ln = "Settings >"; break; 127 | case MI_ABOUT_PGM: ln = "About >"; break; 128 | 129 | default: 130 | ln = NULL; 131 | break; 132 | } 133 | 134 | return ln; 135 | } 136 | -------------------------------------------------------------------------------- /dmcp/sys/pgm_syscalls.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include 54 | 55 | #include 56 | #include 57 | 58 | void Program_Entry(); 59 | 60 | #ifndef PROGRAM_KEYMAP_ID 61 | #define PROGRAM_KEYMAP_ID 0xffffffff 62 | #endif 63 | 64 | prog_info_t const prog_info = { 65 | PROG_INFO_MAGIC, // uint32_t pgm_magic; 66 | 0, // uint32_t pgm_size; 67 | (void*)Program_Entry, // void * pgm_entry; 68 | PLATFORM_IFC_CNR, // uint32_t ifc_cnr; 69 | PLATFORM_IFC_VER, // uint32_t ifc_ver; 70 | QSPI_DATA_SIZE, // uint32_t qspi_size; 71 | QSPI_DATA_CRC, // uint32_t qspi_crc; 72 | PROGRAM_NAME, // char pgm_name[16]; 73 | PROGRAM_VERSION, // char pgm_version[16]; 74 | PROGRAM_KEYMAP_ID // uint32_t required_keymap_id; 75 | }; 76 | 77 | 78 | 79 | int _read(int file, char *ptr, int len) 80 | { 81 | return len; 82 | } 83 | 84 | 85 | int _write(int file, char *ptr, int len) 86 | { 87 | // Routed to OS, where it is printed to ITM 88 | #ifdef USER_WRITE 89 | return USER_WRITE(file, ptr, len); 90 | #else 91 | return __sysfn__write(file, ptr, len); 92 | #endif 93 | } 94 | 95 | 96 | int _close(int file) 97 | { 98 | return -1; 99 | } 100 | 101 | 102 | int _fstat(int file, struct stat *st) 103 | { 104 | st->st_mode = S_IFCHR; 105 | return 0; 106 | } 107 | 108 | int _isatty(int file) 109 | { 110 | return 1; 111 | } 112 | 113 | int _lseek(int file, int ptr, int dir) 114 | { 115 | return 0; 116 | } 117 | 118 | int _kill(int pid, int sig) 119 | { 120 | errno = EINVAL; 121 | return -1; 122 | } 123 | 124 | int _getpid(void) 125 | { 126 | return 1; 127 | } 128 | 129 | 130 | 131 | // Remove any debug substitutions 132 | 133 | #ifdef malloc 134 | #undef malloc 135 | #endif 136 | 137 | #ifdef free 138 | #undef free 139 | #endif 140 | 141 | #ifdef calloc 142 | #undef calloc 143 | #endif 144 | 145 | #ifdef realloc 146 | #undef realloc 147 | #endif 148 | 149 | 150 | void free(void *ptr) { 151 | __sysfn_free(ptr); 152 | } 153 | 154 | 155 | void *malloc(size_t size) { 156 | return __sysfn_malloc(size); 157 | } 158 | 159 | 160 | void *calloc(size_t count, size_t nbytes) { 161 | return __sysfn_calloc(count, nbytes); 162 | } 163 | 164 | void *realloc(void *ptr, size_t size) { 165 | return __sysfn_realloc(ptr, size); 166 | } 167 | 168 | 169 | 170 | void * __wrap__malloc_r (struct _reent *pr, size_t size) { 171 | return malloc(size); 172 | } 173 | 174 | void * _calloc_r (struct _reent *pr, size_t nmemb, size_t size) { 175 | return calloc(nmemb, size); 176 | } 177 | 178 | void * _realloc_r (struct _reent *pr, void *ptr, size_t size) { 179 | return realloc(ptr, size); 180 | } 181 | 182 | void _free_r (struct _reent *pr, void *ptr) { 183 | free(ptr); 184 | } 185 | 186 | 187 | void post_main() { 188 | // Just start DMCP 189 | set_reset_magic(RUN_DMCP_MAGIC); 190 | sys_reset(); 191 | } 192 | 193 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ###################################### 2 | # target 3 | ###################################### 4 | TARGET = SDKdemo 5 | 6 | ###################################### 7 | # building variables 8 | ###################################### 9 | # debug build? 10 | ifdef DEBUG 11 | DEBUG = 1 12 | endif 13 | 14 | ####################################### 15 | # pathes 16 | ####################################### 17 | # Build path 18 | BUILD_DIR = build 19 | 20 | # Path to aux build scripts (including trailing /) 21 | # Leave empty for scripts in PATH 22 | BIN_DIR = bin/ 23 | 24 | ###################################### 25 | # System sources 26 | ###################################### 27 | C_INCLUDES += -Idmcp 28 | C_SOURCES += dmcp/sys/pgm_syscalls.c 29 | ASM_SOURCES = dmcp/startup_pgm.s 30 | 31 | ####################################### 32 | # Custom section 33 | ####################################### 34 | 35 | # Includes 36 | C_INCLUDES += -Isrc -Iinc 37 | 38 | # C sources 39 | C_SOURCES += src/main.c 40 | C_SOURCES += src/menu.c 41 | 42 | # C++ sources 43 | #CXX_SOURCES += src/xxx.cc 44 | 45 | # ASM sources 46 | #ASM_SOURCES += src/xxx.s 47 | 48 | # Additional defines 49 | #C_DEFS += -DXXX 50 | 51 | # Intel library related defines 52 | C_DEFS += -DDECIMAL_CALL_BY_REFERENCE=1 -DDECIMAL_GLOBAL_ROUNDING=1 \ 53 | -DDECIMAL_GLOBAL_ROUNDING_ACCESS_FUNCTIONS=1 -DDECIMAL_GLOBAL_EXCEPTION_FLAGS=1 \ 54 | -DDECIMAL_GLOBAL_EXCEPTION_FLAGS_ACCESS_FUNCTIONS=1 55 | 56 | # Libraries 57 | ifeq ($(DEBUG), 1) 58 | LIBS += lib/gcc111libbid_hard.a 59 | else 60 | LIBS += lib/gcc111libbid_hard.a 61 | endif 62 | 63 | # --- 64 | 65 | 66 | ####################################### 67 | # binaries 68 | ####################################### 69 | CC = arm-none-eabi-gcc 70 | CXX = arm-none-eabi-g++ 71 | AS = arm-none-eabi-gcc -x assembler-with-cpp 72 | OBJCOPY = arm-none-eabi-objcopy 73 | AR = arm-none-eabi-ar 74 | SIZE = arm-none-eabi-size 75 | HEX = $(OBJCOPY) -O ihex 76 | BIN = $(OBJCOPY) -O binary -S 77 | 78 | ####################################### 79 | # CFLAGS 80 | ####################################### 81 | # macros for gcc 82 | AS_DEFS = 83 | C_DEFS += -D__weak="__attribute__((weak))" -D__packed="__attribute__((__packed__))" 84 | AS_INCLUDES = 85 | 86 | 87 | CPUFLAGS += -mthumb -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 88 | 89 | 90 | # compile gcc flags 91 | ASFLAGS = $(CPUFLAGS) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections 92 | CFLAGS = $(CPUFLAGS) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections 93 | CFLAGS += -Wno-misleading-indentation -Wno-stringop-truncation 94 | DBGFLAGS = -g 95 | 96 | ifeq ($(DEBUG), 1) 97 | CFLAGS += -O0 -DDEBUG 98 | else 99 | CFLAGS += -O2 100 | endif 101 | 102 | CFLAGS += $(DBGFLAGS) 103 | LDFLAGS += $(DBGFLAGS) 104 | 105 | # Generate dependency information 106 | CFLAGS += -MD -MP -MF .dep/$(@F).d 107 | 108 | ####################################### 109 | # LDFLAGS 110 | ####################################### 111 | # link script 112 | LDSCRIPT = stm32_program.ld 113 | LIBDIR = 114 | LDFLAGS += $(CPUFLAGS) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref 115 | LDFLAGS += -specs=nano.specs 116 | LDFLAGS += -Wl,--gc-sections -Wl,--wrap=_malloc_r 117 | 118 | 119 | # default action: build all 120 | all: $(BUILD_DIR)/$(TARGET).elf 121 | 122 | ####################################### 123 | # build the application 124 | ####################################### 125 | # list of objects 126 | OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) 127 | vpath %.c $(sort $(dir $(C_SOURCES))) 128 | # C++ sources 129 | OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(CXX_SOURCES:.cc=.o))) 130 | vpath %.cc $(sort $(dir $(CXX_SOURCES))) 131 | # list of ASM program objects 132 | OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) 133 | vpath %.s $(sort $(dir $(ASM_SOURCES))) 134 | 135 | CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 136 | 137 | $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 138 | $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ 139 | 140 | $(BUILD_DIR)/%.o: %.cc Makefile | $(BUILD_DIR) 141 | $(CXX) -c $(CXXFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.cc=.lst)) $< -o $@ 142 | 143 | $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) 144 | $(AS) -c $(CFLAGS) $< -o $@ 145 | 146 | $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile 147 | $(CC) $(OBJECTS) $(LDFLAGS) -o $@ 148 | $(OBJCOPY) --remove-section .qspi -O ihex $@ $(BUILD_DIR)/$(TARGET)_flash.hex 149 | $(OBJCOPY) --remove-section .qspi -O binary $@ $(BUILD_DIR)/$(TARGET)_flash.bin 150 | $(OBJCOPY) --only-section .qspi -O ihex $@ $(BUILD_DIR)/$(TARGET)_qspi.hex 151 | $(OBJCOPY) --only-section .qspi -O binary $@ $(BUILD_DIR)/$(TARGET)_qspi.bin 152 | $(BIN_DIR)check_qspi_crc $(TARGET) src/qspi_crc.h || ( $(MAKE) clean && false ) 153 | $(BIN_DIR)add_pgm_chsum build/$(TARGET)_flash.bin build/$(TARGET).pgm 154 | $(SIZE) $@ 155 | 156 | $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) 157 | $(HEX) $< $@ 158 | 159 | $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) 160 | $(BIN) $< $@ 161 | 162 | $(BUILD_DIR): 163 | mkdir -p $@ 164 | 165 | ####################################### 166 | # clean up 167 | ####################################### 168 | clean: 169 | -rm -fR .dep $(BUILD_DIR)/*.o $(BUILD_DIR)/*.lst 170 | 171 | ####################################### 172 | # dependencies 173 | ####################################### 174 | -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) 175 | 176 | .PHONY: clean all 177 | 178 | # *** EOF *** 179 | -------------------------------------------------------------------------------- /stm32_program.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ***************************************************************************** 3 | ** 4 | 5 | ** File : stm32_flash.ld 6 | ** 7 | ** Abstract : Linker script for STM32L476ZG Device with 8 | ** 1024KByte FLASH, 96KByte RAM 9 | ** 10 | ** Set heap size, stack size and stack location according 11 | ** to application requirements. 12 | ** 13 | ** Set memory bank area and size if external memory is used. 14 | ** 15 | ** Target : STMicroelectronics STM32 16 | ** 17 | ** 18 | ** Distribution: The file is distributed as is, without any warranty 19 | ** of any kind. 20 | ** 21 | ** Swissmicros - ld script for STM32 + QSPI 22 | ** 23 | ***************************************************************************** 24 | */ 25 | 26 | /* Specify the memory areas */ 27 | MEMORY 28 | { 29 | /* FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K */ 30 | /* RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K */ 31 | /* RAM0 (xrw) : ORIGIN = 0x10000000, LENGTH = 32K-256 */ 32 | FLASH (rx) : ORIGIN = 0x8050000, LENGTH = 704K 33 | RAM (xrw) : ORIGIN = 0x10000000, LENGTH = 8K 34 | QSPI (rx) : ORIGIN = 0x90000000, LENGTH = 2048K 35 | } 36 | 37 | /* Entry Point */ 38 | ENTRY(Program_Entry) 39 | 40 | 41 | /* Define output sections */ 42 | SECTIONS 43 | { 44 | 45 | .qspi : 46 | { 47 | . = ALIGN(8); 48 | _qspi_start = .; /* create a global symbol at qspi start */ 49 | *(.qspi) /* .qspi sections */ 50 | *(.qspi*) /* .qspi* sections */ 51 | /* ==== Symbols to QSPI - in direct order === */ 52 | *(.rodata.__bid_mod10_18_tbl) 53 | *(.rodata.__bid_convert_table) 54 | *(.rodata.bid_log_table_1) 55 | *(.rodata.bid_log_table_2) 56 | *(.rodata.bid_decimal128_moduli) 57 | *(.rodata.bid_exponents_bid64) 58 | *(.rodata.bid_exponents_binary128) 59 | *(.rodata.bid_breakpoints_binary128) 60 | *(.rodata.bid_breakpoints_bid64) 61 | *(.rodata.bid_multipliers1_binary128) 62 | *(.rodata.bid_multipliers2_bid64) 63 | *(.rodata.bid_multipliers1_bid64) 64 | *(.rodata.bid_multipliers2_binary128) 65 | /* ======================== */ 66 | . = ALIGN(8); 67 | _qspi_end = .; /* define a global symbols at end of qspi */ 68 | 69 | } >QSPI /* AT> FLASH */ 70 | 71 | /* Constant data goes into FLASH */ 72 | .rodata : 73 | { 74 | KEEP(*(.rodata.prog_info)) /* Program info */ 75 | . = ALIGN(64); 76 | *(.rodata) /* .rodata sections (constants, strings, etc.) */ 77 | *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ 78 | . = ALIGN(8); 79 | } >FLASH 80 | 81 | _qspi_init_base = LOADADDR(.qspi); 82 | _qspi_init_length = SIZEOF(.qspi); 83 | 84 | /* The program code and other data goes into FLASH */ 85 | .text : 86 | { 87 | . = ALIGN(8); 88 | *(.text) /* .text sections (code) */ 89 | *(.text*) /* .text* sections (code) */ 90 | *(.glue_7) /* glue arm to thumb code */ 91 | *(.glue_7t) /* glue thumb to arm code */ 92 | *(.eh_frame) 93 | 94 | KEEP (*(.init)) 95 | KEEP (*(.fini)) 96 | 97 | . = ALIGN(8); 98 | _etext = .; /* define a global symbols at end of code */ 99 | } >FLASH 100 | 101 | .ARM.extab : 102 | { 103 | . = ALIGN(8); 104 | *(.ARM.extab* .gnu.linkonce.armextab.*) 105 | . = ALIGN(8); 106 | } >FLASH 107 | .ARM : { 108 | . = ALIGN(8); 109 | __exidx_start = .; 110 | *(.ARM.exidx*) 111 | __exidx_end = .; 112 | . = ALIGN(8); 113 | } >FLASH 114 | 115 | .preinit_array : 116 | { 117 | . = ALIGN(8); 118 | PROVIDE_HIDDEN (__preinit_array_start = .); 119 | KEEP (*(.preinit_array*)) 120 | PROVIDE_HIDDEN (__preinit_array_end = .); 121 | . = ALIGN(8); 122 | } >FLASH 123 | 124 | .init_array : 125 | { 126 | . = ALIGN(8); 127 | PROVIDE_HIDDEN (__init_array_start = .); 128 | KEEP (*(SORT(.init_array.*))) 129 | KEEP (*(.init_array*)) 130 | PROVIDE_HIDDEN (__init_array_end = .); 131 | . = ALIGN(8); 132 | } >FLASH 133 | .fini_array : 134 | { 135 | . = ALIGN(8); 136 | PROVIDE_HIDDEN (__fini_array_start = .); 137 | KEEP (*(SORT(.fini_array.*))) 138 | KEEP (*(.fini_array*)) 139 | PROVIDE_HIDDEN (__fini_array_end = .); 140 | . = ALIGN(8); 141 | } >FLASH 142 | 143 | /* used by the startup to initialize data */ 144 | _sidata = LOADADDR(.data); 145 | 146 | /* Initialized data sections goes into RAM, load LMA copy after code */ 147 | .data : 148 | { 149 | . = ALIGN(8); 150 | _sdata = .; /* create a global symbol at data start */ 151 | *(.data.sdb) /* SDB at the beginning of the RAM0 */ 152 | *(.data) /* .data sections */ 153 | *(.data*) /* .data* sections */ 154 | 155 | . = ALIGN(8); 156 | _edata = .; /* define a global symbol at data end */ 157 | } >RAM AT> FLASH 158 | 159 | /* Uninitialized data section */ 160 | . = ALIGN(4); 161 | .bss : 162 | { 163 | /* This is used by the startup in order to initialize the .bss secion */ 164 | _sbss = .; /* define a global symbol at bss start */ 165 | __bss_start__ = _sbss; 166 | *(.bss) 167 | *(.bss*) 168 | *(COMMON) 169 | 170 | . = ALIGN(4); 171 | _ebss = .; /* define a global symbol at bss end */ 172 | __bss_end__ = _ebss; 173 | } >RAM AT> RAM 174 | 175 | /* Remove information from the standard libraries */ 176 | /DISCARD/ : 177 | { 178 | libc.a ( * ) 179 | libm.a ( * ) 180 | libgcc.a ( * ) 181 | } 182 | 183 | .ARM.attributes 0 : { *(.ARM.attributes) } 184 | } 185 | 186 | 187 | -------------------------------------------------------------------------------- /dmcp/ff_ifc.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __FF_IFC_H__ 44 | #define __FF_IFC_H__ 45 | 46 | 47 | 48 | /* These types MUST be 16-bit or 32-bit */ 49 | typedef int INT; 50 | typedef unsigned int UINT; 51 | 52 | /* This type MUST be 8-bit */ 53 | typedef unsigned char BYTE; 54 | 55 | /* These types MUST be 16-bit */ 56 | typedef short SHORT; 57 | typedef unsigned short WORD; 58 | typedef unsigned short WCHAR; 59 | 60 | /* These types MUST be 32-bit */ 61 | typedef long LONG; 62 | typedef unsigned long DWORD; 63 | 64 | /* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */ 65 | typedef unsigned long long QWORD; 66 | 67 | typedef char TCHAR; 68 | #define _T(x) x 69 | #define _TEXT(x) x 70 | 71 | typedef DWORD FSIZE_t; 72 | 73 | typedef struct __FATFS FATFS; 74 | 75 | 76 | typedef struct { 77 | FATFS* fs; 78 | WORD id; 79 | BYTE attr; 80 | BYTE stat; 81 | DWORD sclust; 82 | FSIZE_t objsize; 83 | UINT lockid; 84 | } _FDID; 85 | 86 | typedef struct { 87 | _FDID obj; 88 | BYTE flag; 89 | BYTE err; 90 | FSIZE_t fptr; 91 | DWORD clust; 92 | DWORD sect; 93 | DWORD dir_sect; 94 | BYTE* dir_ptr; 95 | DWORD* cltbl; 96 | BYTE buf[512]; 97 | } FIL; 98 | 99 | 100 | /* File access mode and open method flags (3rd argument of f_open) */ 101 | #define FA_READ 0x01 102 | #define FA_WRITE 0x02 103 | #define FA_OPEN_EXISTING 0x00 104 | #define FA_CREATE_NEW 0x04 105 | #define FA_CREATE_ALWAYS 0x08 106 | #define FA_OPEN_ALWAYS 0x10 107 | #define FA_OPEN_APPEND 0x30 108 | 109 | 110 | 111 | /* File function return code (FRESULT) */ 112 | 113 | typedef enum { 114 | FR_OK = 0, /* (0) Succeeded */ 115 | FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ 116 | FR_INT_ERR, /* (2) Assertion failed */ 117 | FR_NOT_READY, /* (3) The physical drive cannot work */ 118 | FR_NO_FILE, /* (4) Could not find the file */ 119 | FR_NO_PATH, /* (5) Could not find the path */ 120 | FR_INVALID_NAME, /* (6) The path name format is invalid */ 121 | FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ 122 | FR_EXIST, /* (8) Access denied due to prohibited access */ 123 | FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ 124 | FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ 125 | FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ 126 | FR_NOT_ENABLED, /* (12) The volume has no work area */ 127 | FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ 128 | FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */ 129 | FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ 130 | FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ 131 | FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ 132 | FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */ 133 | FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ 134 | } FRESULT; 135 | 136 | 137 | 138 | FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ 139 | FRESULT f_close (FIL* fp); /* Close an open file object */ 140 | FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */ 141 | FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */ 142 | FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ 143 | FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ 144 | FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ 145 | 146 | #define f_size(fp) ((fp)->obj.objsize) 147 | #define f_tell(fp) ((fp)->fptr) 148 | #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) 149 | 150 | #ifndef EOF 151 | #define EOF (-1) 152 | #endif 153 | 154 | #endif 155 | -------------------------------------------------------------------------------- /help/sdkdemo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Quick Reference Guide 6 | 7 | 15 | 16 | 17 |

SDK Demo Quick Reference Guide

18 |
19 | Example help file 20 |
21 |

Navigation

22 | Press + to move one line forward
23 | Press - to move one line backward
24 | Press × to move one page forward
25 | Press ÷ to move one page backward
26 |
27 | 28 | 29 |

Symbols used in this guide

30 | A 123 represents a soft button or anything on the LCD
31 | A STO represents a physical button
32 |
33 |

Contents

34 | 44 |

45 | 46 |

About Help Browser

47 | The DMCP system supports extremely lightweight implementation of HTML which covers just 48 | small fraction of the format. Almost all supported formatting is used in this help file. 49 |
50 | If you want to write your own help file it is strongly recommended to take this help file 51 | as starting point and follow the structure of the HTML. Then check the appearance in 52 | calculator browser, whether it looks as expected.
53 |
54 | See "Special characters available" for list of supported 55 | characters in help file. 56 |

57 | 58 | 59 |

Stack

60 | Stack consists of 10 registers. All arithmetic operations use for arguments and results 61 | top level of the stack as is usual for RPN machines.
62 | Stack registers could be also accessed using 63 | RCL and STO 64 | with negative indexes -1 to -9.
65 |
66 | Example of stack display:
67 | 6: 0
68 | 5: 0
69 | 4: 0
70 | 3: 0
71 | 2: 321232.123ᴇ-12
72 | 1: 54.344234342
73 | 0: 123.32
74 |
75 | 76 |

Registers

77 | Register area consist of 100 registers. Registers could be accessed using 78 | RCL and STO 79 | with indexes 0 to 99.
80 |
81 | 82 | 83 |

Fx Buttons without menu

84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
F1Displays this Help
F2
F3
F4
F5Decreases font size
F6Increases font size
92 |

93 | 94 | 95 |

Angular Modes

96 | Pressing MODES button cycles through angular modes 97 | 98 | 99 | 100 | 101 |
DEG Degrees
RADRadians
GRADGradians

102 |
103 | Current angular mode is displayed in status line. 104 |

105 | 106 | 107 |

Number Formats

108 | Press DISP - selection menu appears 109 | 110 | 111 | 112 | 113 | 114 |
NoneNo special format
FIX Fixed decimal places (ARG)
SCI Scientific notation (ARG)
ENG Engineering notation (ARG)

115 | (ARG): Takes number of fractional digits (i.e. digits after decimal point) 116 | as argument from stack. 117 |

118 | 119 | 120 |

Implemented functions

121 | [1/x], 122 | [√x], 123 | [LOG], 124 | [LN], 125 |
126 | 127 | [x2], 128 | [yx], 129 | [10x], 130 | [ex], 131 |
132 | 133 | [STO], 134 | [RCL], 135 | [R↓], 136 | [SIN], 137 | [COS], 138 | [TAN], 139 |
140 | 141 | [%], 142 | [π], 143 | [ASIN], 144 | [ACOS], 145 | [ATAN], 146 |
147 | 148 |

149 | 150 | 151 |

Special characters available

152 | This list of special characters supported in help files.
153 | HTML &xxx; sequences
154 | Unicode characters 155 | 165 |
166 | 167 | 168 |

HTML &xxx; sequences

169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 |
' 'as &nbsp;
&as &amp;
>as &gt;
<as &lt;
as &#9660;
as &#9650;
as &darr;
as &uarr;
as &larr;
as &rarr;
as &int;
±as &plusmn;
÷as &divide;
×as &times;
Σas &Sigma;
188 |

189 | 190 |

Unicode characters

191 | U+xxxx notation means Unicode character placed directly in help file. 192 |

193 | 194 |

Letters

195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 |
ÄU+00C4
ÅU+00C5
ÆU+00C6
ÑU+00D1
ÖU+00D6
ÜU+00DC
U+1D07
204 |

205 | 206 |

Ligatures

207 | 208 | 209 | 210 |
U+FB01
U+FB02
211 |

212 | 213 |

Greek

214 | 215 | 216 | 217 | 218 | 219 | 220 |
ΣU+03A3
μU+03BC
πU+03C0
ΓU+0393 (Transliterated)
θU+03B8 (Transliterated)
221 |

222 | 223 |

Punctuation marks

224 | 225 | 226 | 227 | 228 | 229 |
U+2014
U+2019
U+2026
¿U+00BF
230 |

231 | 232 |

Arrows

233 | 234 | 235 | 236 | 237 | 238 | 239 |
U+2190
U+2191
U+2192
U+2193
U+21B2
240 |

241 | 242 |

Symbols

243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 |
°U+00B0
×U+00D7
÷U+00F7
U+221A
U+2220 or U+2221
U+222B
U+2260
U+2264
U+2265
U+240A
U+241B
£U+00A3
257 |

258 | 259 |

Graphics

260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 |
U+2592
U+25A0
U+25B6
U+25BC
U+25B2
U+25C4
268 |

269 | 270 | 271 |

272 | 273 | 274 | -------------------------------------------------------------------------------- /dmcp/lft_ifc.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | 44 | #define LIBRARY_FN_BASE 0x08000201 45 | 46 | #define __sysfn_malloc (*(typeof(malloc)*)(LIBRARY_FN_BASE+0)) 47 | #define __sysfn_free (*(typeof(free)*)(LIBRARY_FN_BASE+4)) 48 | #define __sysfn_calloc (*(typeof(calloc)*)(LIBRARY_FN_BASE+8)) 49 | #define __sysfn_realloc (*(typeof(realloc)*)(LIBRARY_FN_BASE+12)) 50 | #define __sysfn__write (*(typeof(_write)*)(LIBRARY_FN_BASE+16)) 51 | #define LCD_clear (*(typeof(LCD_clear)*)(LIBRARY_FN_BASE+20)) 52 | #define LCD_power_on (*(typeof(LCD_power_on)*)(LIBRARY_FN_BASE+24)) 53 | #define LCD_power_off (*(typeof(LCD_power_off)*)(LIBRARY_FN_BASE+28)) 54 | #define LCD_write_line (*(typeof(LCD_write_line)*)(LIBRARY_FN_BASE+32)) 55 | #define bitblt24 (*(typeof(bitblt24)*)(LIBRARY_FN_BASE+36)) 56 | #define lcd_line_addr (*(typeof(lcd_line_addr)*)(LIBRARY_FN_BASE+40)) 57 | #define lcd_clear_buf (*(typeof(lcd_clear_buf)*)(LIBRARY_FN_BASE+44)) 58 | #define lcd_refresh (*(typeof(lcd_refresh)*)(LIBRARY_FN_BASE+48)) 59 | #define lcd_forced_refresh (*(typeof(lcd_forced_refresh)*)(LIBRARY_FN_BASE+52)) 60 | #define lcd_refresh_lines (*(typeof(lcd_refresh_lines)*)(LIBRARY_FN_BASE+56)) 61 | #define lcd_fill_rect (*(typeof(lcd_fill_rect)*)(LIBRARY_FN_BASE+60)) 62 | #define lcd_draw_img (*(typeof(lcd_draw_img)*)(LIBRARY_FN_BASE+64)) 63 | #define lcd_draw_img_direct (*(typeof(lcd_draw_img_direct)*)(LIBRARY_FN_BASE+68)) 64 | #define lcd_draw_img_part (*(typeof(lcd_draw_img_part)*)(LIBRARY_FN_BASE+72)) 65 | #define lcd_fillLine (*(typeof(lcd_fillLine)*)(LIBRARY_FN_BASE+76)) 66 | #define lcd_fillLines (*(typeof(lcd_fillLines)*)(LIBRARY_FN_BASE+80)) 67 | #define lcd_set_buf_cleared (*(typeof(lcd_set_buf_cleared)*)(LIBRARY_FN_BASE+84)) 68 | #define lcd_get_buf_cleared (*(typeof(lcd_get_buf_cleared)*)(LIBRARY_FN_BASE+88)) 69 | #define lcd_writeNl (*(typeof(lcd_writeNl)*)(LIBRARY_FN_BASE+92)) 70 | #define lcd_prevLn (*(typeof(lcd_prevLn)*)(LIBRARY_FN_BASE+96)) 71 | #define lcd_writeClr (*(typeof(lcd_writeClr)*)(LIBRARY_FN_BASE+100)) 72 | #define lcd_setLine (*(typeof(lcd_setLine)*)(LIBRARY_FN_BASE+104)) 73 | #define lcd_setXY (*(typeof(lcd_setXY)*)(LIBRARY_FN_BASE+108)) 74 | #define lcd_lineHeight (*(typeof(lcd_lineHeight)*)(LIBRARY_FN_BASE+112)) 75 | #define lcd_baseHeight (*(typeof(lcd_baseHeight)*)(LIBRARY_FN_BASE+116)) 76 | #define lcd_fontWidth (*(typeof(lcd_fontWidth)*)(LIBRARY_FN_BASE+120)) 77 | #define lcd_writeText (*(typeof(lcd_writeText)*)(LIBRARY_FN_BASE+124)) 78 | #define lcd_textWidth (*(typeof(lcd_textWidth)*)(LIBRARY_FN_BASE+128)) 79 | #define lcd_charWidth (*(typeof(lcd_charWidth)*)(LIBRARY_FN_BASE+132)) 80 | #define lcd_textToWidth (*(typeof(lcd_textToWidth)*)(LIBRARY_FN_BASE+136)) 81 | #define lcd_writeTextWidth (*(typeof(lcd_writeTextWidth)*)(LIBRARY_FN_BASE+140)) 82 | #define lcd_textForWidth (*(typeof(lcd_textForWidth)*)(LIBRARY_FN_BASE+144)) 83 | #define lcd_nextFontNr (*(typeof(lcd_nextFontNr)*)(LIBRARY_FN_BASE+148)) 84 | #define lcd_prevFontNr (*(typeof(lcd_prevFontNr)*)(LIBRARY_FN_BASE+152)) 85 | #define lcd_switchFont (*(typeof(lcd_switchFont)*)(LIBRARY_FN_BASE+156)) 86 | #define lcd_toggleFontT (*(typeof(lcd_toggleFontT)*)(LIBRARY_FN_BASE+160)) 87 | #define lcd_draw_menu_bg (*(typeof(lcd_draw_menu_bg)*)(LIBRARY_FN_BASE+164)) 88 | #define lcd_draw_menu_key (*(typeof(lcd_draw_menu_key)*)(LIBRARY_FN_BASE+168)) 89 | #define lcd_draw_menu_keys (*(typeof(lcd_draw_menu_keys)*)(LIBRARY_FN_BASE+172)) 90 | #define lcd_print (*(typeof(lcd_print)*)(LIBRARY_FN_BASE+176)) 91 | #define lcd_for_calc (*(typeof(lcd_for_calc)*)(LIBRARY_FN_BASE+180)) 92 | #define get_wday_shortcut (*(typeof(get_wday_shortcut)*)(LIBRARY_FN_BASE+184)) 93 | #define get_month_shortcut (*(typeof(get_month_shortcut)*)(LIBRARY_FN_BASE+188)) 94 | #define julian_day (*(typeof(julian_day)*)(LIBRARY_FN_BASE+192)) 95 | #define julian_to_date (*(typeof(julian_to_date)*)(LIBRARY_FN_BASE+196)) 96 | #define get_hw_id (*(typeof(get_hw_id)*)(LIBRARY_FN_BASE+200)) 97 | #define rtc_read (*(typeof(rtc_read)*)(LIBRARY_FN_BASE+204)) 98 | #define rtc_write (*(typeof(rtc_write)*)(LIBRARY_FN_BASE+208)) 99 | #define rtc_read_century (*(typeof(rtc_read_century)*)(LIBRARY_FN_BASE+212)) 100 | #define rtc_write_century (*(typeof(rtc_write_century)*)(LIBRARY_FN_BASE+216)) 101 | #define rtc_read_min (*(typeof(rtc_read_min)*)(LIBRARY_FN_BASE+220)) 102 | #define rtc_read_sec (*(typeof(rtc_read_sec)*)(LIBRARY_FN_BASE+224)) 103 | #define rtc_wakeup_delay (*(typeof(rtc_wakeup_delay)*)(LIBRARY_FN_BASE+228)) 104 | #define read_power_voltage (*(typeof(read_power_voltage)*)(LIBRARY_FN_BASE+232)) 105 | #define get_lowbat_state (*(typeof(get_lowbat_state)*)(LIBRARY_FN_BASE+236)) 106 | #define get_vbat (*(typeof(get_vbat)*)(LIBRARY_FN_BASE+240)) 107 | #define start_buzzer_freq (*(typeof(start_buzzer_freq)*)(LIBRARY_FN_BASE+244)) 108 | #define stop_buzzer (*(typeof(stop_buzzer)*)(LIBRARY_FN_BASE+248)) 109 | #define beep_volume_up (*(typeof(beep_volume_up)*)(LIBRARY_FN_BASE+252)) 110 | #define beep_volume_down (*(typeof(beep_volume_down)*)(LIBRARY_FN_BASE+256)) 111 | #define get_beep_volume (*(typeof(get_beep_volume)*)(LIBRARY_FN_BASE+260)) 112 | #define mark_region (*(typeof(mark_region)*)(LIBRARY_FN_BASE+264)) 113 | #define no_region (*(typeof(no_region)*)(LIBRARY_FN_BASE+268)) 114 | #define set_reset_magic (*(typeof(set_reset_magic)*)(LIBRARY_FN_BASE+272)) 115 | #define is_reset_state_file (*(typeof(is_reset_state_file)*)(LIBRARY_FN_BASE+276)) 116 | #define get_reset_state_file (*(typeof(get_reset_state_file)*)(LIBRARY_FN_BASE+280)) 117 | #define set_reset_state_file (*(typeof(set_reset_state_file)*)(LIBRARY_FN_BASE+284)) 118 | #define usb_powered (*(typeof(usb_powered)*)(LIBRARY_FN_BASE+288)) 119 | #define aux_buf_ptr (*(typeof(aux_buf_ptr)*)(LIBRARY_FN_BASE+292)) 120 | #define write_buf_ptr (*(typeof(write_buf_ptr)*)(LIBRARY_FN_BASE+296)) 121 | #define print_byte (*(typeof(print_byte)*)(LIBRARY_FN_BASE+300)) 122 | #define printer_get_delay (*(typeof(printer_get_delay)*)(LIBRARY_FN_BASE+304)) 123 | #define printer_set_delay (*(typeof(printer_set_delay)*)(LIBRARY_FN_BASE+308)) 124 | #define printer_advance_buf (*(typeof(printer_advance_buf)*)(LIBRARY_FN_BASE+312)) 125 | #define printer_busy_for (*(typeof(printer_busy_for)*)(LIBRARY_FN_BASE+316)) 126 | #define rtc_check_unset (*(typeof(rtc_check_unset)*)(LIBRARY_FN_BASE+320)) 127 | #define run_set_time (*(typeof(run_set_time)*)(LIBRARY_FN_BASE+324)) 128 | #define run_set_date (*(typeof(run_set_date)*)(LIBRARY_FN_BASE+328)) 129 | #define disp_disk_info (*(typeof(disp_disk_info)*)(LIBRARY_FN_BASE+332)) 130 | #define file_selection_screen (*(typeof(file_selection_screen)*)(LIBRARY_FN_BASE+336)) 131 | #define power_check_screen (*(typeof(power_check_screen)*)(LIBRARY_FN_BASE+340)) 132 | #define handle_menu (*(typeof(handle_menu)*)(LIBRARY_FN_BASE+344)) 133 | #define rb_str (*(typeof(rb_str)*)(LIBRARY_FN_BASE+348)) 134 | #define sel_str (*(typeof(sel_str)*)(LIBRARY_FN_BASE+352)) 135 | #define opt_str (*(typeof(opt_str)*)(LIBRARY_FN_BASE+356)) 136 | #define date_str (*(typeof(date_str)*)(LIBRARY_FN_BASE+360)) 137 | #define time_str (*(typeof(time_str)*)(LIBRARY_FN_BASE+364)) 138 | #define read_file_items (*(typeof(read_file_items)*)(LIBRARY_FN_BASE+368)) 139 | #define sort_file_items (*(typeof(sort_file_items)*)(LIBRARY_FN_BASE+372)) 140 | #define create_screenshot (*(typeof(create_screenshot)*)(LIBRARY_FN_BASE+376)) 141 | #define key_empty (*(typeof(key_empty)*)(LIBRARY_FN_BASE+380)) 142 | #define key_push (*(typeof(key_push)*)(LIBRARY_FN_BASE+384)) 143 | #define key_tail (*(typeof(key_tail)*)(LIBRARY_FN_BASE+388)) 144 | #define key_pop (*(typeof(key_pop)*)(LIBRARY_FN_BASE+392)) 145 | #define key_pop_last (*(typeof(key_pop_last)*)(LIBRARY_FN_BASE+396)) 146 | #define key_pop_all (*(typeof(key_pop_all)*)(LIBRARY_FN_BASE+400)) 147 | #define key_to_nr (*(typeof(key_to_nr)*)(LIBRARY_FN_BASE+404)) 148 | #define wait_for_key_press (*(typeof(wait_for_key_press)*)(LIBRARY_FN_BASE+408)) 149 | #define runner_get_key (*(typeof(runner_get_key)*)(LIBRARY_FN_BASE+412)) 150 | #define runner_get_key_delay (*(typeof(runner_get_key_delay)*)(LIBRARY_FN_BASE+416)) 151 | #define wait_for_key_release (*(typeof(wait_for_key_release)*)(LIBRARY_FN_BASE+420)) 152 | #define runner_key_tout_value (*(typeof(runner_key_tout_value)*)(LIBRARY_FN_BASE+424)) 153 | #define runner_key_tout_init (*(typeof(runner_key_tout_init)*)(LIBRARY_FN_BASE+428)) 154 | #define toggle_slow_autorepeat (*(typeof(toggle_slow_autorepeat)*)(LIBRARY_FN_BASE+432)) 155 | #define is_slow_autorepeat (*(typeof(is_slow_autorepeat)*)(LIBRARY_FN_BASE+436)) 156 | #define reset_auto_off (*(typeof(reset_auto_off)*)(LIBRARY_FN_BASE+440)) 157 | #define is_auto_off (*(typeof(is_auto_off)*)(LIBRARY_FN_BASE+444)) 158 | #define is_menu_auto_off (*(typeof(is_menu_auto_off)*)(LIBRARY_FN_BASE+448)) 159 | #define sys_auto_off_cnt (*(typeof(sys_auto_off_cnt)*)(LIBRARY_FN_BASE+452)) 160 | #define print_dmy_date (*(typeof(print_dmy_date)*)(LIBRARY_FN_BASE+456)) 161 | #define print_clk24_time (*(typeof(print_clk24_time)*)(LIBRARY_FN_BASE+460)) 162 | #define check_create_dir (*(typeof(check_create_dir)*)(LIBRARY_FN_BASE+464)) 163 | #define set_fat_label (*(typeof(set_fat_label)*)(LIBRARY_FN_BASE+468)) 164 | #define file_exists (*(typeof(file_exists)*)(LIBRARY_FN_BASE+472)) 165 | #define sys_disk_ok (*(typeof(sys_disk_ok)*)(LIBRARY_FN_BASE+476)) 166 | #define sys_disk_write_enable (*(typeof(sys_disk_write_enable)*)(LIBRARY_FN_BASE+480)) 167 | #define sys_disk_check_valid (*(typeof(sys_disk_check_valid)*)(LIBRARY_FN_BASE+484)) 168 | #define sys_is_disk_write_enable (*(typeof(sys_is_disk_write_enable)*)(LIBRARY_FN_BASE+488)) 169 | #define sys_clear_write_buf_used (*(typeof(sys_clear_write_buf_used)*)(LIBRARY_FN_BASE+492)) 170 | #define sys_write_buf_used (*(typeof(sys_write_buf_used)*)(LIBRARY_FN_BASE+496)) 171 | #define sys_timer_disable (*(typeof(sys_timer_disable)*)(LIBRARY_FN_BASE+500)) 172 | #define sys_timer_start (*(typeof(sys_timer_start)*)(LIBRARY_FN_BASE+504)) 173 | #define sys_timer_active (*(typeof(sys_timer_active)*)(LIBRARY_FN_BASE+508)) 174 | #define sys_timer_timeout (*(typeof(sys_timer_timeout)*)(LIBRARY_FN_BASE+512)) 175 | #define sys_delay (*(typeof(sys_delay)*)(LIBRARY_FN_BASE+516)) 176 | #define sys_tick_count (*(typeof(sys_tick_count)*)(LIBRARY_FN_BASE+520)) 177 | #define sys_current_ms (*(typeof(sys_current_ms)*)(LIBRARY_FN_BASE+524)) 178 | #define sys_critical_start (*(typeof(sys_critical_start)*)(LIBRARY_FN_BASE+528)) 179 | #define sys_critical_end (*(typeof(sys_critical_end)*)(LIBRARY_FN_BASE+532)) 180 | #define sys_sleep (*(typeof(sys_sleep)*)(LIBRARY_FN_BASE+536)) 181 | #define sys_free_mem (*(typeof(sys_free_mem)*)(LIBRARY_FN_BASE+540)) 182 | #define sys_reset (*(typeof(sys_reset)*)(LIBRARY_FN_BASE+544)) 183 | #define sys_last_key (*(typeof(sys_last_key)*)(LIBRARY_FN_BASE+548)) 184 | #define run_help (*(typeof(run_help)*)(LIBRARY_FN_BASE+552)) 185 | #define draw_power_off_image (*(typeof(draw_power_off_image)*)(LIBRARY_FN_BASE+556)) 186 | #define reset_off_image_cycle (*(typeof(reset_off_image_cycle)*)(LIBRARY_FN_BASE+560)) 187 | #define f_open (*(typeof(f_open)*)(LIBRARY_FN_BASE+564)) 188 | #define f_close (*(typeof(f_close)*)(LIBRARY_FN_BASE+568)) 189 | #define f_read (*(typeof(f_read)*)(LIBRARY_FN_BASE+572)) 190 | #define f_write (*(typeof(f_write)*)(LIBRARY_FN_BASE+576)) 191 | #define f_lseek (*(typeof(f_lseek)*)(LIBRARY_FN_BASE+580)) 192 | #define run_help_file (*(typeof(run_help_file)*)(LIBRARY_FN_BASE+584)) 193 | #define set_buzzer (*(typeof(set_buzzer)*)(LIBRARY_FN_BASE+588)) 194 | #define __sysfn_read_key (*(typeof(read_key)*)(LIBRARY_FN_BASE+592)) 195 | #define get_tim1_timer (*(typeof(get_tim1_timer)*)(LIBRARY_FN_BASE+596)) 196 | #define update_bmp_file_header (*(typeof(update_bmp_file_header)*)(LIBRARY_FN_BASE+600)) 197 | #define make_date_filename (*(typeof(make_date_filename)*)(LIBRARY_FN_BASE+604)) 198 | #define reverse_byte (*(typeof(reverse_byte)*)(LIBRARY_FN_BASE+608)) 199 | #define f_rename (*(typeof(f_rename)*)(LIBRARY_FN_BASE+612)) 200 | #define file_size (*(typeof(file_size)*)(LIBRARY_FN_BASE+616)) 201 | #define start_timer2 (*(typeof(start_timer2)*)(LIBRARY_FN_BASE+620)) 202 | #define start_timer3 (*(typeof(start_timer3)*)(LIBRARY_FN_BASE+624)) 203 | #define stop_timer2 (*(typeof(stop_timer2)*)(LIBRARY_FN_BASE+628)) 204 | #define stop_timer3 (*(typeof(stop_timer3)*)(LIBRARY_FN_BASE+632)) 205 | #define __sysfn_suspended_bg_key_read (*(typeof(suspended_bg_key_read)*)(LIBRARY_FN_BASE+636)) 206 | #define __sysfn_resume_bg_key_read (*(typeof(resume_bg_key_read)*)(LIBRARY_FN_BASE+640)) 207 | #define lcd_refresh_dma (*(typeof(lcd_refresh_dma)*)(LIBRARY_FN_BASE+644)) 208 | #define lcd_refresh_wait (*(typeof(lcd_refresh_wait)*)(LIBRARY_FN_BASE+648)) 209 | #define lcd_textToBox (*(typeof(lcd_textToBox)*)(LIBRARY_FN_BASE+652)) 210 | #define item_sel_init (*(typeof(item_sel_init)*)(LIBRARY_FN_BASE+656)) 211 | #define item_sel_reinit (*(typeof(item_sel_reinit)*)(LIBRARY_FN_BASE+660)) 212 | #define item_sel_header (*(typeof(item_sel_header)*)(LIBRARY_FN_BASE+664)) 213 | #define item_sel_engine (*(typeof(item_sel_engine)*)(LIBRARY_FN_BASE+668)) 214 | #define sys_flashing_init (*(typeof(sys_flashing_init)*)(LIBRARY_FN_BASE+672)) 215 | #define sys_flashing_finish (*(typeof(sys_flashing_finish)*)(LIBRARY_FN_BASE+676)) 216 | #define sys_flash_erase_block (*(typeof(sys_flash_erase_block)*)(LIBRARY_FN_BASE+680)) 217 | #define sys_flash_write_block (*(typeof(sys_flash_write_block)*)(LIBRARY_FN_BASE+684)) 218 | #define msg_box (*(typeof(msg_box)*)(LIBRARY_FN_BASE+688)) 219 | #define write_buf_size (*(typeof(write_buf_size)*)(LIBRARY_FN_BASE+692)) 220 | #define get_rtc_ticks (*(typeof(get_rtc_ticks)*)(LIBRARY_FN_BASE+696)) 221 | #define rtc_update_ticks (*(typeof(rtc_update_ticks)*)(LIBRARY_FN_BASE+700)) 222 | #define rtc_set_alarm (*(typeof(rtc_set_alarm)*)(LIBRARY_FN_BASE+704)) 223 | #define rtc_cancel_alarm (*(typeof(rtc_cancel_alarm)*)(LIBRARY_FN_BASE+708)) 224 | #define rtc_update_time_sec (*(typeof(rtc_update_time_sec)*)(LIBRARY_FN_BASE+712)) 225 | #define run_help_file_style (*(typeof(run_help_file_style)*)(LIBRARY_FN_BASE+716)) 226 | #define print_buffer (*(typeof(print_buffer)*)(LIBRARY_FN_BASE+720)) 227 | #define print_is_ready (*(typeof(print_is_ready)*)(LIBRARY_FN_BASE+724)) 228 | #define run_menu_item_sys (*(typeof(run_menu_item_sys)*)(LIBRARY_FN_BASE+728)) 229 | #define lcd_fill_ptrn (*(typeof(lcd_fill_ptrn)*)(LIBRARY_FN_BASE+732)) 230 | #define usb_acm_on (*(typeof(usb_acm_on)*)(LIBRARY_FN_BASE+736)) 231 | #define usb_turn_off (*(typeof(usb_turn_off)*)(LIBRARY_FN_BASE+740)) 232 | #define usb_is_on (*(typeof(usb_is_on)*)(LIBRARY_FN_BASE+744)) 233 | #define acm_puts (*(typeof(acm_puts)*)(LIBRARY_FN_BASE+748)) 234 | #define switch_usb_powered_freq (*(typeof(switch_usb_powered_freq)*)(LIBRARY_FN_BASE+752)) 235 | #define qspi_user_write (*(typeof(qspi_user_write)*)(LIBRARY_FN_BASE+756)) 236 | #define qspi_user_addr (*(typeof(qspi_user_addr)*)(LIBRARY_FN_BASE+760)) 237 | #define qspi_user_size (*(typeof(qspi_user_size)*)(LIBRARY_FN_BASE+764)) 238 | #define f_unlink (*(typeof(f_unlink)*)(LIBRARY_FN_BASE+768)) 239 | #define sys_last_scan (*(typeof(sys_last_scan)*)(LIBRARY_FN_BASE+772)) 240 | #define sys_largest_free_mem (*(typeof(sys_largest_free_mem)*)(LIBRARY_FN_BASE+776)) 241 | #define sys_request (*(typeof(sys_request)*)(LIBRARY_FN_BASE+780)) 242 | #define qrcode_disp (*(typeof(qrcode_disp)*)(LIBRARY_FN_BASE+784)) 243 | #define qrcode_getBufferSize (*(typeof(qrcode_getBufferSize)*)(LIBRARY_FN_BASE+788)) 244 | #define qrcode_initText (*(typeof(qrcode_initText)*)(LIBRARY_FN_BASE+792)) 245 | #define qrcode_initBytes (*(typeof(qrcode_initBytes)*)(LIBRARY_FN_BASE+796)) 246 | #define qrcode_getModule (*(typeof(qrcode_getModule)*)(LIBRARY_FN_BASE+800)) 247 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | 44 | #include 45 | #include 46 | #include 47 | 48 | #include 49 | #include 50 | 51 | #include 52 | #include 53 | 54 | 55 | 56 | #ifndef max 57 | #define max(x,y) ({ \ 58 | __typeof__ (x) _x = (x); \ 59 | __typeof__ (y) _y = (y); \ 60 | _x > _y ? _x : _y; }) 61 | #endif 62 | 63 | #ifndef min 64 | #define min(x,y) ({ \ 65 | __typeof__ (x) _x = (x); \ 66 | __typeof__ (y) _y = (y); \ 67 | _x < _y ? _x : _y; }) 68 | #endif 69 | 70 | #define strend(s) (s + strlen(s)) 71 | 72 | 73 | 74 | // ================================================== 75 | // Prototypes 76 | // ================================================== 77 | void stack_dup(); 78 | void stack_pop(); 79 | void stack_clear(); 80 | void clear_regs(); 81 | 82 | 83 | 84 | // ================================================== 85 | // == Util functions 86 | // ================================================== 87 | 88 | 89 | void beep(int freq, int dur) { 90 | start_buzzer_freq(freq*1000); 91 | sys_delay(dur); 92 | stop_buzzer(); 93 | } 94 | 95 | 96 | void make_screenshot() { 97 | // Start click 98 | start_buzzer_freq(4400); sys_delay(10); stop_buzzer(); 99 | // Make screenshot - allow to report errors 100 | if ( create_screenshot(1) == 2 ) { 101 | // Was error just wait for confirmation 102 | wait_for_key_press(); 103 | } 104 | // End click 105 | start_buzzer_freq(8800); sys_delay(10); stop_buzzer(); 106 | } 107 | 108 | 109 | // ================================================== 110 | 111 | #define MAX_LINE_SIZE 51 112 | 113 | #define STACK_SIZE 10 114 | #define REGS_SIZE 100 115 | 116 | #define ANG_MODE_DEG 0 117 | #define ANG_MODE_RAD 1 118 | #define ANG_MODE_GRAD 2 119 | #define ANG_MODE_CNT 3 120 | 121 | 122 | // ---------------- 123 | // Calc state 124 | // ---------------- 125 | 126 | num_t stack[STACK_SIZE]; 127 | num_t regs[REGS_SIZE]; 128 | 129 | // -- Input/Edit -- 130 | uint8_t shift; 131 | uint8_t edit; 132 | uint8_t ang_mode; 133 | uint8_t fmt_mode; 134 | uint8_t fmt_mode_digits; 135 | char ed[MAX_LINE_SIZE]; 136 | const char expchar = 'E'; 137 | char dotchar = '.'; 138 | 139 | int reg_font_ix = 3; 140 | 141 | // -- Constants -- 142 | num_t num_zero; 143 | num_t num_one; 144 | num_t num_10; 145 | num_t num_pi; 146 | num_t num_pi_180; 147 | num_t num_180_pi; 148 | num_t num_pi_200; 149 | num_t num_200_pi; 150 | num_t num_1_100; 151 | // ---------------- 152 | 153 | #define FM_BASE 0x300 154 | #define FM_DISP_NONE (FM_BASE | 1) 155 | #define FM_DISP_FIX (FM_BASE | 2) 156 | #define FM_DISP_SCI (FM_BASE | 3) 157 | #define FM_DISP_ENG (FM_BASE | 4) 158 | 159 | const char ** f_menu = NULL; 160 | const int * f_menu_fns = NULL; 161 | const char *fm_disp[] = {"None","FIX","SCI","ENG","",""}; 162 | const int fm_disp_fns[] = {FM_DISP_NONE, FM_DISP_FIX, FM_DISP_SCI, FM_DISP_ENG,0,0}; 163 | 164 | // ---------------- 165 | 166 | 167 | #define FMT_MODE_NONE 0 168 | #define FMT_MODE_FIX 1 169 | #define FMT_MODE_SCI 2 170 | #define FMT_MODE_ENG 3 171 | #define FMT_MODE_CNT 4 172 | 173 | #define MAX_NUM_CHARS 50 // 1ms+34m+1E+1es+4e ...enough for BID128 174 | #define MAX_NEG_FILL 4 // Allow decimal point and 4 zeros in front of mantissa 175 | 176 | 177 | // Returns 1/0 whether it was/wasn't overflow (resp.) 178 | // ix - index of first rounded digit 179 | int round_string(char * s, int ix, char rounding_digit) { 180 | 181 | if (rounding_digit + 5 <= '9') 182 | return 0; 183 | 184 | for( ; ix >=0; ix--) { 185 | if (s[ix] == '.') 186 | continue; // Skip decimal point 187 | s[ix]++; 188 | if (s[ix] <= '9' ) 189 | return 0; 190 | s[ix] -= 10; 191 | } 192 | 193 | return 1; 194 | } 195 | 196 | 197 | void num_format(num_t * num, char *str, int len, int mode, int mode_digits) { 198 | char s[MAX_NUM_CHARS]; 199 | num_to_string(s,num); 200 | 201 | for(;;) { 202 | char * ep = strchr(s,expchar); 203 | 204 | if (!ep) { // No exponent -> expecting special number, just copy 205 | strcpy(str,s); 206 | return; 207 | } 208 | 209 | int ms = s[0] == '-'; // Mantissa negative 210 | int mexp = ep-s-1; // Mantissa exponent (if point placed before first digit) 211 | int isexp = 1; 212 | int exp = atoi(ep+1)+mexp; // Exp to num and translate to point before first mantissa digit 213 | int elen; 214 | int a,b,c; // Aux vars 215 | char * mp; 216 | 217 | // Terminate mantissa string 218 | char * mend = ep-1; // Mantissa end 219 | char * mant = s+1; // Mantissa string 220 | // Ignore mantissa trailing zeros 221 | while (ep > mant && mend[0] == '0') mend--; 222 | *(++mend) = 0; 223 | 224 | // Exponent: yes or no? 225 | switch (mode) { 226 | case FMT_MODE_FIX: 227 | if ( exp <= 0 && mode_digits <= -exp ) break; // Zero fill bigger then mode digits 228 | case FMT_MODE_NONE: 229 | // == Check if exponent is needed 230 | b = exp; 231 | if (exp >= (-MAX_NEG_FILL+1)) { 232 | if (exp <= 0) // Number requires '0.' and zero padding after decimal point 233 | b+= 2-exp+1; // to at least one mantissa digit after padding zeros 234 | if (ms) b++; // One place for sign 235 | isexp = b > len; // Number cannot fit without exponent 236 | } 237 | break; 238 | 239 | case FMT_MODE_SCI: 240 | case FMT_MODE_ENG: 241 | break; 242 | } 243 | 244 | // --- 245 | int dbp = isexp ? 1 : exp; // Digits before point 246 | int mlen = strlen(s+1); // Available mantissa digits 247 | 248 | // Exponent correction for ENG mode 249 | exp--; // fix for dbp==1 250 | if ( mode == FMT_MODE_ENG ) { 251 | // Lower the exponent to nearest multiple of 3 252 | b = exp>=0 ? exp%3 : 2+(exp-2)%3; 253 | exp -= b; 254 | dbp += b; 255 | } 256 | 257 | int zfad = max(0, -dbp); // zero fill after dot 258 | 259 | // Prepare exponent 260 | if (isexp) { 261 | ep++; // not interfere with possible mantissa end 262 | sprintf(ep, "%c%i", expchar, exp); 263 | elen = strlen(ep); // Count the E char 264 | } else { 265 | ep[0] = 0; 266 | elen = 0; 267 | } 268 | 269 | // Complete number 270 | const char * zeros = "00000000000000000000000000000000000000"; 271 | b = mlen-dbp; // Frac digits available 272 | 273 | // Add Mantissa 274 | strcpy(str, ms ? "-" : ""); 275 | strncat(str, s+1, c=max(dbp,0)); mp = s+1+min(c,strlen(s+1)); 276 | strncat(str, zeros, max(-b,0)); 277 | 278 | // Add frac 279 | a = len - strlen(str) - elen; // Available space 280 | mode_digits = min(mode==FMT_MODE_NONE ? b : mode_digits, a-1-(dbp>0?0:1)); 281 | 282 | if (mode_digits > 0) { // We have digits and have room for at least one frac digit 283 | strcat(str, dbp > 0 ? "." : "0."); b = max(0,b); 284 | strncat(str, zeros, zfad); mode_digits-=zfad; 285 | strncat(str, mp, c=min(b,mode_digits)); mp += c; 286 | strncat(str, zeros, max(mode_digits+zfad-b,0)); 287 | } 288 | 289 | if (*mp) { // More mantissa digits available -> rounding 290 | int rix = mp-s; 291 | int ovfl = round_string(str+ms, strlen(str+ms)-1, s[rix]); 292 | if (ovfl) { 293 | sprintf(s,"%c1%c%c%i",ms?'-':'+',expchar,exp<0?'-':'+', abs(exp+1)); 294 | continue; // goto in disguise 295 | } 296 | if (mode == FMT_MODE_NONE) { 297 | // Remove trailing zeros 298 | int ix = strlen(str)-1; 299 | while (ix && str[ix] == '0') ix--; 300 | if (str[ix] == '.') ix--; 301 | str[ix+1] = 0; 302 | } 303 | } 304 | // Add exp 305 | strcat(str,ep); 306 | break; 307 | } 308 | } 309 | 310 | 311 | // ---------------- 312 | 313 | 314 | void disp_stack_line(char * s, int a, int cpl) { 315 | sprintf(s,"%i:",a); 316 | 317 | if ( edit && a == 0 ) { 318 | strcat(s, ed); 319 | strcat(s, "_"); 320 | } else { 321 | num_format(stack+a, strend(s), cpl-strlen(s), fmt_mode, fmt_mode_digits); 322 | //num_to_string(strend(s), stack+a); 323 | } 324 | char *t = strchr(s,expchar); if (t) *t = '\x98'; 325 | } 326 | 327 | 328 | void disp_annun(int xpos, const char * txt) { 329 | t20->lnfill = 0; // Don't clear line (we expect dark background already drawn) 330 | t20->x = xpos; // Align 331 | t20->y -= 2; 332 | // White rectangle for text 333 | lcd_fill_rect(t20->x, 1, lcd_textWidth(t20, txt), lcd_lineHeight(t20)-5, 0); 334 | lcd_puts(t20, txt); 335 | t20->y += 2; 336 | t20->lnfill = 1; // Return default state 337 | } 338 | 339 | 340 | const char *ang_mode_ann[ANG_MODE_CNT] = {"[DEG]", "[RAD]", "[GRAD]"}; 341 | 342 | void redraw_lcd() { 343 | char s[MAX_LINE_SIZE]; 344 | const int top_y_lines = lcd_lineHeight(t20); 345 | 346 | lcd_clear_buf(); 347 | 348 | // == Header == 349 | lcd_writeClr(t20); 350 | t20->newln = 0; // No skip to next line 351 | 352 | lcd_putsR(t20, "SDK DEMO"); 353 | 354 | // Annunciators 355 | disp_annun(270, ang_mode_ann[ang_mode]); 356 | if (shift) 357 | disp_annun(330, "[SHIFT]"); 358 | if (fmt_mode != FMT_MODE_NONE) { 359 | sprintf(s,"[%s|%i]",fm_disp[fmt_mode],fmt_mode_digits); 360 | disp_annun(180, s); 361 | } 362 | 363 | t20->newln = 1; // Revert to default 364 | 365 | // == Menu == 366 | if (f_menu) 367 | lcd_draw_menu_keys(f_menu); 368 | 369 | // == Stack == 370 | lcd_writeClr(fReg); 371 | lcd_switchFont(fReg, reg_font_ix); 372 | fReg->y = LCD_Y-(f_menu?LCD_MENU_LINES:0); 373 | fReg->newln = 0; 374 | const int cpl = (LCD_X - fReg->xoffs)/lcd_fontWidth(fReg); // Chars per line 375 | printf("Font: X=%i xoffs=%i fw=%i cpl=%i\n", LCD_X, fReg->xoffs, lcd_fontWidth(fReg), cpl); 376 | for(int a=0; a < STACK_SIZE; a++) { 377 | lcd_prevLn(fReg); 378 | if ( fReg->y <= top_y_lines ) 379 | break; 380 | disp_stack_line(s, a, cpl); 381 | lcd_puts(fReg,s); 382 | } 383 | 384 | lcd_refresh(); 385 | } 386 | 387 | 388 | 389 | 390 | // ================================================== 391 | // Editing 392 | // ================================================== 393 | const char key_to_char[] = "_" // code 0 unused 394 | "______" 395 | "______" 396 | "_____" 397 | "_789_" 398 | "_456_" 399 | "_123_" 400 | "_0.__"; 401 | 402 | #define MAX_ED_CHARS 37 403 | 404 | void start_edit() { 405 | strcpy(ed,"0"); 406 | edit = 1; 407 | stack_dup(); 408 | } 409 | 410 | void cancel_edit() { 411 | edit = 0; 412 | stack_pop(); 413 | } 414 | 415 | void finish_edit() { 416 | // Store edited number to X 417 | num_from_string(stack, ed); 418 | edit = 0; 419 | } 420 | 421 | 422 | int ed_cat(char c, int len) { 423 | if ( len >= MAX_ED_CHARS ) 424 | return len; 425 | 426 | ed[len++] = c; 427 | ed[len] = 0; 428 | return len; 429 | } 430 | 431 | int ed_del(char * at, int len) { 432 | memmove(at, at+1, len); 433 | return len-1; 434 | } 435 | 436 | int ed_ins(char * at, char c, int len) { 437 | if ( len >= MAX_ED_CHARS ) 438 | return len; 439 | 440 | memmove(at+1, at, ++len); 441 | at[0] = c; 442 | return len; 443 | } 444 | 445 | 446 | void add_edit_key(int key) { 447 | 448 | if ( !edit ) 449 | start_edit(); 450 | 451 | int len = strlen(ed); 452 | 453 | char * dot = strchr(ed, dotchar); 454 | char * exp = strchr(ed, expchar); 455 | 456 | switch (key) { 457 | case KEY_DOT: 458 | if ( dot || exp ) return; // It has already dot or no dots in exponents 459 | len = ed_cat(dotchar, len); 460 | break; 461 | 462 | case KEY_E: 463 | if ( exp ) return; // It has already exponent 464 | len = ed_cat(expchar, len); 465 | return; 466 | 467 | case KEY_CHS: 468 | if ( exp ) 469 | // Change exp sign 470 | len = ( exp[1] == '-' ) ? ed_del(exp+1, len) : ed_ins(exp+1, '-', len); 471 | else 472 | // Change mantissa sign 473 | len = ( ed[0] == '-' ) ? ed_del(ed, len) : ed_ins(ed, '-', len); 474 | break; 475 | 476 | case KEY_BSP: 477 | ed[--len] = 0; 478 | if (len == 0) 479 | cancel_edit(); // Leaving edit when removed last edited char 480 | break; 481 | 482 | default: // Numbers 483 | if ( !dot && ((len == 1 && ed[0] == '0') || (ed[len-1] == '0' && !isdigit((int)ed[len-2]))) ) 484 | ed[--len] = 0; // Remove redundant 0 485 | ed_cat(key_to_char[key], len); 486 | break; 487 | } 488 | 489 | 490 | } 491 | 492 | 493 | // ================================================== 494 | // Functions 495 | // ================================================== 496 | 497 | #define FNSH 0x100 498 | 499 | 500 | void stack_clear() { 501 | for(int a=0; a0 ? regs+(ix%REGS_SIZE) : stack+((1-ix)%STACK_SIZE); 519 | } 520 | 521 | int reg_to_fmt_num(num_t *a) { 522 | int k; 523 | num_to_int(&k, a); 524 | return min(abs(k), NUM_MAX_MANTISSA_DIGITS); 525 | } 526 | 527 | // Angle conversions (according to ang_mode) 528 | num_t * TO_RAD(num_t *y, num_t *x) { 529 | switch(ang_mode) { 530 | case ANG_MODE_RAD: *y = *x; break; 531 | case ANG_MODE_DEG: num_mul(y, x, &num_pi_180); break; 532 | case ANG_MODE_GRAD: num_mul(y, x, &num_pi_200); break; 533 | } 534 | return y; 535 | } 536 | 537 | num_t * FROM_RAD(num_t *y, num_t *x) { 538 | switch(ang_mode) { 539 | case ANG_MODE_RAD: *y = *x; break; 540 | case ANG_MODE_DEG: num_mul(y, x, &num_180_pi); break; 541 | case ANG_MODE_GRAD: num_mul(y, x, &num_200_pi); break; 542 | } 543 | return y; 544 | } 545 | 546 | 547 | #define RES1 stack[0] = res 548 | #define RES2 stack_pop(); RES1 549 | 550 | 551 | int run_fn(int key) { 552 | int consumed = 1; 553 | num_t res; 554 | int fnr = key + (shift<<8); 555 | 556 | if (edit) 557 | finish_edit(); 558 | 559 | switch (fnr) { 560 | 561 | case KEY_BSP | FNSH: stack_clear(); break; //clear_regs(); 562 | 563 | case KEY_BSP: 564 | case KEY_RDN: stack_pop(); break; 565 | 566 | case KEY_RDN | FNSH: stack_dup(); stack[0] = num_pi; break; 567 | case KEY_STO: reg_by_ix(stack)[0] = stack[1]; stack_pop(); break; 568 | case KEY_RCL: stack[0] = reg_by_ix(stack)[0]; break; 569 | case KEY_RCL | FNSH: num_mul(&res, stack+1, stack); stack_pop(); num_mul(stack,&res,&num_1_100); break; 570 | 571 | case KEY_ADD: num_add(&res, stack+1, stack); RES2; break; 572 | case KEY_SUB: num_sub(&res, stack+1, stack); RES2; break; 573 | case KEY_MUL: num_mul(&res, stack+1, stack); RES2; break; 574 | case KEY_DIV: num_div(&res, stack+1, stack); RES2; break; 575 | 576 | case KEY_INV: num_div(&res, &num_one, stack); RES1; break; 577 | case KEY_SQRT: num_sqrt(&res, stack); RES1; break; 578 | case KEY_LOG: num_log10(&res, stack); RES1; break; 579 | case KEY_LN: num_log(&res,stack); RES1; break; 580 | 581 | case KEY_INV | FNSH: num_pow(&res, stack+1, stack); RES2; break; 582 | case KEY_SQRT | FNSH: num_mul(&res, stack, stack); RES1; break; 583 | case KEY_LOG | FNSH: num_exp10(&res, stack); RES1; break; 584 | case KEY_LN | FNSH: num_exp(&res,stack); RES1; break; 585 | 586 | case KEY_SIN: num_sin(stack, TO_RAD(&res, stack)); break; 587 | case KEY_COS: num_cos(stack, TO_RAD(&res, stack)); break; 588 | case KEY_TAN: num_tan(stack, TO_RAD(&res, stack)); break; 589 | 590 | case KEY_SIN | FNSH: num_asin(&res, stack); FROM_RAD(stack, &res); break; 591 | case KEY_COS | FNSH: num_acos(&res, stack); FROM_RAD(stack, &res); break; 592 | case KEY_TAN | FNSH: num_atan(&res, stack); FROM_RAD(stack, &res); break; 593 | 594 | case KEY_SWAP: res=stack[0]; stack[0]=stack[1]; stack[1]=res; break; 595 | case KEY_CHS: num_sub(&res, &num_zero, stack); RES1; break; 596 | 597 | case FM_DISP_FIX: 598 | case FM_DISP_ENG: 599 | case FM_DISP_SCI: 600 | fmt_mode_digits = reg_to_fmt_num(stack); stack_pop(); 601 | case FM_DISP_NONE: 602 | fmt_mode = fnr - FM_DISP_NONE; 603 | break; 604 | 605 | 606 | case 777: 607 | // Just some nonsense fill to have the same QSPI contents as DM42 608 | #if 1 609 | { 610 | double d = key; 611 | BID_UINT64 a; 612 | binary64_to_bid64(&a, &d); 613 | bid64_to_bid128(&res, &a); 614 | } 615 | #endif 616 | break; 617 | default: 618 | consumed = 0; 619 | break; 620 | } 621 | 622 | return consumed; 623 | } 624 | 625 | // ================================================== 626 | 627 | void handle_fmenu(int key) { 628 | if (!f_menu) return; 629 | 630 | if (f_menu_fns) { 631 | int ix = key-KEY_F1; 632 | int fm_key = f_menu_fns[ix]; 633 | if(fm_key) run_fn(fm_key); 634 | } 635 | 636 | f_menu = NULL; 637 | } 638 | 639 | // ================================================== 640 | 641 | 642 | void handle_key(int key) { 643 | int consumed = 0; 644 | 645 | printf("HK: key[%02x] sh[%i] ed[%i]\n", key, shift, edit); 646 | 647 | // Handle fmenu keys 648 | if (f_menu) { 649 | consumed = 1; 650 | switch(key) { 651 | case KEY_F1: case KEY_F2: case KEY_F3: 652 | case KEY_F4: case KEY_F5: case KEY_F6: 653 | handle_fmenu(key); 654 | break; 655 | default: 656 | consumed=0; 657 | break; 658 | } 659 | } 660 | 661 | // Keys independent on shift state 662 | if (!consumed) { 663 | consumed = 1; 664 | switch(key) { 665 | case KEY_SCREENSHOT: 666 | make_screenshot(); 667 | break; 668 | case KEY_DOUBLE_RELEASE: 669 | break; 670 | 671 | case KEY_SUB: case KEY_ADD: case KEY_MUL: case KEY_DIV: 672 | case KEY_INV: case KEY_SQRT: case KEY_LOG: case KEY_LN: 673 | case KEY_RCL: case KEY_STO: 674 | case KEY_RDN: case KEY_SIN: case KEY_COS: case KEY_TAN: 675 | case KEY_SWAP: 676 | consumed = run_fn(key); 677 | break; 678 | 679 | case KEY_F1: 680 | run_help_file("/HELP/sdkdemo.html"); 681 | break; 682 | 683 | case KEY_F5: // F5 = Decrease font size 684 | reg_font_ix = lcd_prevFontNr(reg_font_ix); 685 | break; 686 | case KEY_F6: // F6 = Increase font size 687 | reg_font_ix = lcd_nextFontNr(reg_font_ix); 688 | break; 689 | 690 | default: 691 | consumed = 0; 692 | break; 693 | } 694 | if (consumed) shift=0; 695 | } 696 | 697 | 698 | if (!consumed && shift) { 699 | consumed = 1; 700 | switch(key) { 701 | case KEY_0: 702 | SET_ST(STAT_MENU); 703 | //int ret = 704 | handle_menu(&MID_MENU, MENU_RESET, 0); // App menu 705 | CLR_ST(STAT_MENU); 706 | wait_for_key_release(-1); 707 | break; 708 | 709 | case KEY_ENTER: 710 | if (edit) 711 | cancel_edit(); 712 | stack_pop(); 713 | break; 714 | 715 | case KEY_CHS: // MODES 716 | ang_mode = (ang_mode+1) % ANG_MODE_CNT; 717 | break; 718 | 719 | case KEY_BSP: 720 | if (edit) 721 | add_edit_key(key); 722 | else 723 | run_fn(key); 724 | break; 725 | 726 | case KEY_E: // DISP 727 | f_menu = fm_disp; 728 | f_menu_fns = fm_disp_fns; 729 | break; 730 | 731 | case KEY_SHIFT: 732 | break; 733 | 734 | default: 735 | consumed = 0; 736 | break; 737 | } 738 | if (key != 0) 739 | shift = 0; 740 | } 741 | 742 | if (!consumed) { 743 | consumed = 1; 744 | switch(key) { 745 | case KEY_SHIFT: 746 | shift = 1; 747 | break; 748 | 749 | case KEY_EXIT: 750 | SET_ST(STAT_PGM_END); 751 | break; 752 | 753 | case KEY_ENTER: 754 | if (edit) 755 | finish_edit(); 756 | else 757 | stack_dup(); 758 | break; 759 | 760 | case KEY_BSP: 761 | case KEY_CHS: 762 | if (edit) 763 | add_edit_key(key); 764 | else 765 | run_fn(key); 766 | break; 767 | 768 | case KEY_0: case KEY_1: case KEY_2: case KEY_3: case KEY_4: 769 | case KEY_5: case KEY_6: case KEY_7: case KEY_8: case KEY_9: 770 | case KEY_DOT: 771 | case KEY_E: 772 | add_edit_key(key); 773 | break; 774 | 775 | 776 | default: 777 | consumed = 0; 778 | break; 779 | } 780 | } 781 | 782 | if (!consumed && key != 0) { 783 | beep(1835, 125); 784 | } 785 | 786 | 787 | } 788 | 789 | 790 | 791 | void clear_regs() { 792 | // Set regs to zeroes 793 | for(int a=0; a just continue to sleep above 890 | continue; 891 | } 892 | 893 | // Well, we are woken-up 894 | SET_ST(STAT_RUNNING); 895 | 896 | // Clear suspended state, because now we are definitely reached the active state 897 | CLR_ST(STAT_SUSPENDED); 898 | 899 | 900 | // Get up from OFF state 901 | if ( ST(STAT_OFF) ) { 902 | LCD_power_on(); 903 | rtc_wakeup_delay(); // Ensure that RTC readings after power off will be OK 904 | 905 | CLR_ST(STAT_OFF); 906 | 907 | if ( !lcd_get_buf_cleared() ) 908 | lcd_forced_refresh(); // Just redraw from LCD buffer 909 | } 910 | 911 | 912 | // Key is ready -> clear auto off timer 913 | if ( !key_empty() ) 914 | reset_auto_off(); 915 | 916 | 917 | // Fetch the key 918 | // < 0 -> No key event 919 | // > 0 -> Key pressed 920 | // == 0 -> Key released 921 | key = key_pop(); 922 | 923 | if (key >= 0) 924 | handle_key(key); 925 | 926 | redraw_lcd(); 927 | } 928 | 929 | } 930 | 931 | 932 | 933 | 934 | -------------------------------------------------------------------------------- /dmcp/dmcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __SYS_DMCP_H__ 44 | #define __SYS_DMCP_H__ 45 | 46 | #include 47 | 48 | typedef unsigned int uint; 49 | 50 | #include "ff_ifc.h" 51 | #include "qrcode.h" 52 | 53 | // ---------------------------------- 54 | 55 | 56 | // Configuration 57 | #define LCD_INVERT_XAXIS 58 | #define LCD_INVERT_DATA 59 | // ------- 60 | 61 | 62 | #define BLT_OR 0 63 | #define BLT_ANDN 1 64 | #define BLT_XOR 2 // 3 65 | 66 | #define BLT_NONE 0 67 | #define BLT_SET 1 68 | 69 | 70 | #ifdef LCD_INVERT_DATA 71 | # define LCD_EMPTY_VALUE 0xFF 72 | # define LCD_SET_VALUE 0 73 | #else 74 | # define LCD_EMPTY_VALUE 0 75 | # define LCD_SET_VALUE 0xFF 76 | #endif 77 | 78 | 79 | 80 | // HW interface 81 | void LCD_clear(); 82 | void LCD_power_on(); 83 | void LCD_power_off(int clear); 84 | void LCD_write_line(uint8_t * buf); 85 | 86 | 87 | void bitblt24(uint32_t x, uint32_t dx, uint32_t y, uint32_t val, int blt_op, int fill); 88 | 89 | // Returns pointer to line buffer (doesn't depend on LCD_INVERT_XAXIS) 90 | uint8_t * lcd_line_addr(int y); 91 | 92 | // Drawing Prototypes 93 | void lcd_clear_buf(); 94 | void lcd_refresh(); 95 | void lcd_refresh_dma(); 96 | void lcd_refresh_wait(); 97 | void lcd_forced_refresh(); 98 | void lcd_refresh_lines(int ln, int cnt); 99 | 100 | 101 | void lcd_fill_rect(uint32_t x, uint32_t y, uint32_t dx, uint32_t dy, int val); 102 | void lcd_fill_ptrn(int x, int y, int dx, int dy, int ptrn1, int ptrn2); 103 | 104 | // Place image into LCD buffer 105 | void lcd_draw_img(const char* img, uint32_t xo, uint32_t yo, uint32_t x, uint32_t y); 106 | void lcd_draw_img_direct(const char* img, uint32_t xo, uint32_t yo, uint32_t x, uint32_t y); 107 | void lcd_draw_img_part(const char* img, uint32_t xo, uint32_t yo, uint32_t x, uint32_t y, uint32_t dx); 108 | 109 | #define LCD_X 400 110 | #define LCD_Y 240 111 | #define LCD_LINE_SIZE 50 // LCD_X/8 112 | #define LCD_LINE_BUF_SIZE (2+LCD_LINE_SIZE+2) // CMD, Line_nr, line data (50 bytes), dummy (2 bytes) 113 | 114 | void lcd_fillLine(int ln, uint8_t val); 115 | void lcd_fillLines(int ln, uint8_t val, int cnt); 116 | 117 | 118 | void lcd_set_buf_cleared(int val); 119 | int lcd_get_buf_cleared(); 120 | 121 | uint8_t reverse_byte(uint8_t x); 122 | 123 | 124 | // ---------------------------------- 125 | 126 | 127 | // Font structure 128 | typedef struct { 129 | const char * name; 130 | uint8_t width; 131 | uint8_t height; 132 | uint8_t baseline; 133 | uint8_t first_char; 134 | uint8_t char_cnt; 135 | uint8_t scale_x; 136 | uint8_t scale_y; 137 | uint8_t const * data; 138 | uint16_t const * offs; 139 | } line_font_t; 140 | 141 | 142 | #define NR2T(x) (-(x)-1) // x<0 143 | #define T2NR(x) (-(x)-1) // x>=0 144 | 145 | // Font display state 146 | typedef struct { 147 | line_font_t const * f; // Current font 148 | int16_t x, y; // Current x,y position 149 | int16_t ln_offs; // Line offset (when displaying by line numbers) 150 | int16_t y_top_grd; // Don't overwrite anything above this line 151 | int8_t ya; // Lines to fill above the font 152 | int8_t yb; // Lines to fill below the font 153 | int8_t xspc; // Space between chars 154 | int8_t xoffs; // X offset for first char on line 155 | 156 | uint8_t fixed; // Draw in fixed width 157 | uint8_t inv; // Draw inverted 158 | uint8_t bgfill; // Fill background while drawing 159 | uint8_t lnfill; // Fill whole lines before writing line 160 | uint8_t newln; // New line after writing line 161 | const uint8_t *post_offs; // X-advance character width minus this value (if not-null) 162 | } disp_stat_t; 163 | 164 | void lcd_writeNl(disp_stat_t * ds); 165 | void lcd_prevLn(disp_stat_t * ds); 166 | void lcd_writeClr(disp_stat_t * ds); 167 | void lcd_setLine(disp_stat_t * ds, int ln_nr); 168 | void lcd_setXY(disp_stat_t * ds, int x, int y); 169 | 170 | int lcd_lineHeight(disp_stat_t * ds); 171 | int lcd_baseHeight(disp_stat_t * ds); 172 | int lcd_fontWidth(disp_stat_t * ds); 173 | 174 | // Font display functions 175 | void lcd_writeText(disp_stat_t * ds, const char* text); 176 | // Note that 'text' has to be in RAM 177 | void lcd_textToBox(disp_stat_t * ds, int x, int width, char *text, int from_right, int align_right); 178 | 179 | // Width calculation functions 180 | int lcd_textWidth(disp_stat_t * ds, const char* text); 181 | int lcd_charWidth(disp_stat_t * ds, int c); 182 | 183 | // Get just text which fits in expected_width 184 | // Returns index of char which breaks the space limit 185 | // Optional plen variable can be supplied to get text width up to index limit. 186 | int lcd_textToWidth(disp_stat_t * ds, const char* text, int expected_width, int * plen); 187 | // ... alternative version to upper function which takes text from the end 188 | // returns -1 if whole text fits into 'expected_width' 189 | int lcd_textToWidthR(disp_stat_t * ds, const char* text, int expected_width, int * plen); 190 | 191 | // Just advance ds->x don't print anything 192 | void lcd_writeTextWidth(disp_stat_t * ds, const char* text); 193 | 194 | // Get text which fits in expected width *without breaking words* 195 | // - word could be broken in the middle only when is placed single long word on line 196 | int lcd_textForWidth(disp_stat_t * ds, const char* text, int expected_width, int * plen); 197 | 198 | 199 | // Font switching 200 | int lcd_nextFontNr(int nr); 201 | int lcd_prevFontNr(int nr); 202 | void lcd_switchFont(disp_stat_t * ds, int nr); 203 | int lcd_toggleFontT(int nr); 204 | 205 | 206 | // ---------------------------------- 207 | 208 | 209 | // Display screens for calc 210 | #define DISP_CALC 0 211 | #define DISP_SYS_MENU 2 212 | #define DISP_BOOTLOADER 4 213 | #define DISP_UNIMPLEMENTED 5 214 | #define DISP_USB_WRITE 6 215 | #define DISP_MSC_CONNECT_USB 7 216 | #define DISP_ABOUT 8 217 | #define DISP_FAT_FORMAT 9 218 | #define DISP_FAULT 11 219 | #define DISP_QSPI_BAD_CRC 12 220 | #define DISP_QSPI_CHECK 13 221 | #define DISP_MARK_REGION 15 222 | #define DISP_DISK_TEST 16 223 | #define DISP_DSKTST_CONNECT_USB 17 224 | #define DISP_QSPI_CONNECT_USB 18 225 | #define DISP_OFF_IMAGE_ERR 19 226 | #define DISP_HELP 21 227 | #define DISP_BOOTLDR_CON_USB 22 228 | #define DISP_PROD_DIAG 23 229 | #define DISP_POWER_CHECK 24 230 | #define DISP_FLASH_CONNECT_USB 26 231 | // ---- 232 | 233 | 234 | // Display predefined screen by number 235 | int lcd_for_calc(int what); 236 | 237 | 238 | // == Menu keys 239 | 240 | #define LCD_MENU_LINES 32 241 | 242 | #define MENU_KEY_LABEL_LEN 12 243 | #define MENU_KEY_COUNT 6 244 | 245 | void lcd_draw_menu_bg(); 246 | void lcd_draw_menu_key(int n, const char *s, int highlight); 247 | void lcd_draw_menu_keys(const char *keys[]); 248 | 249 | void lcd_print(disp_stat_t * ds, const char* fmt, ...); 250 | 251 | #define lcd_printAt(ds, ln, ...) do { lcd_setLine(ds, ln); lcd_print(ds, __VA_ARGS__); } while(0) 252 | #define lcd_printR(ds, ...) do { ds->inv=1; lcd_print(ds, __VA_ARGS__); ds->inv=0; } while(0) 253 | #define lcd_printRAt(ds, ln, ...) do { lcd_setLine(ds, ln); ds->inv=1; lcd_print(ds, __VA_ARGS__); ds->inv=0; } while(0) 254 | 255 | #define lcd_puts lcd_writeText 256 | #define lcd_putsAt(ds, ln, str) do { lcd_setLine(ds, ln); lcd_puts(ds,str); } while(0) 257 | #define lcd_putsR(ds, str) do { ds->inv=1; lcd_puts(ds,str); ds->inv=0; } while(0) 258 | #define lcd_putsRAt(ds, ln, str) do { lcd_setLine(ds, ln); ds->inv=1; lcd_puts(ds,str); ds->inv=0; } while(0) 259 | 260 | 261 | // ---------------------------------- 262 | 263 | 264 | typedef struct { 265 | uint16_t year; 266 | uint8_t month; 267 | uint8_t day; 268 | } dt_t; 269 | 270 | typedef struct { 271 | uint8_t hour; 272 | uint8_t min; 273 | uint8_t sec; 274 | uint8_t csec; 275 | uint8_t dow; 276 | } tm_t; 277 | 278 | const char* get_wday_shortcut(int day); // 0 = Monday 279 | const char* get_month_shortcut(int month); // 1 = Jan 280 | 281 | // DOW is julian_day % 7 ... where 0 = Mon 282 | int julian_day(dt_t *d); 283 | void julian_to_date(int julian_day, dt_t *d); 284 | 285 | 286 | // ---------------------------------- 287 | 288 | // System data block 289 | 290 | typedef int get_flag_fn_t(); 291 | typedef void set_flag_fn_t(int val); 292 | 293 | typedef int run_menu_item_fn_t(uint8_t line_id); 294 | typedef const char * menu_line_str_fn_t(uint8_t line_id, char * s, const int slen); 295 | 296 | typedef void void_fn_t(); 297 | 298 | 299 | typedef struct { 300 | volatile uint32_t calc_state; 301 | FIL * ppgm_fp; 302 | const char * key_to_alpha_table; 303 | 304 | run_menu_item_fn_t * run_menu_item_app; 305 | menu_line_str_fn_t * menu_line_str_app; 306 | 307 | void_fn_t * after_fat_format; 308 | 309 | get_flag_fn_t * get_flag_dmy; 310 | set_flag_fn_t * set_flag_dmy; 311 | get_flag_fn_t * is_flag_clk24; 312 | set_flag_fn_t * set_flag_clk24; 313 | get_flag_fn_t * is_beep_mute; 314 | set_flag_fn_t * set_beep_mute; 315 | 316 | disp_stat_t * pds_t20; 317 | disp_stat_t * pds_t24; 318 | disp_stat_t * pds_fReg; 319 | 320 | uint32_t * timer2_counter; 321 | uint32_t * timer3_counter; 322 | 323 | void_fn_t * msc_end_cb; 324 | 325 | } sys_sdb_t; 326 | 327 | 328 | #define calc_state (sdb.calc_state) 329 | #define ppgm_fp (sdb.ppgm_fp) 330 | 331 | #define key_to_alpha_table (sdb.key_to_alpha_table) 332 | 333 | #define run_menu_item_app (sdb.run_menu_item_app) 334 | #define menu_line_str_app (sdb.menu_line_str_app) 335 | 336 | #define after_fat_format (sdb.after_fat_format) 337 | 338 | #define get_flag_dmy (sdb.get_flag_dmy) 339 | #define set_flag_dmy (sdb.set_flag_dmy) 340 | #define is_flag_clk24 (sdb.is_flag_clk24) 341 | #define set_flag_clk24 (sdb.set_flag_clk24) 342 | #define is_beep_mute (sdb.is_beep_mute) 343 | #define set_beep_mute (sdb.set_beep_mute) 344 | #define timer2_counter (sdb.timer2_counter) 345 | #define timer3_counter (sdb.timer3_counter) 346 | 347 | #define msc_end_cb (sdb.msc_end_cb) 348 | 349 | 350 | #define t20 (sdb.pds_t20) 351 | #define t24 (sdb.pds_t24) 352 | #define fReg (sdb.pds_fReg) 353 | 354 | #define sdb (*((sys_sdb_t*)0x10002000)) 355 | 356 | 357 | // ---------------------------------- 358 | 359 | #define PLATFORM_VERSION "3.29" 360 | 361 | // System interface version 362 | #define PLATFORM_IFC_CNR 3 363 | #define PLATFORM_IFC_VER 17 364 | 365 | // STATIC_ASSERT ... 366 | #define ASSERT_CONCAT_(a, b) a##b 367 | #define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b) 368 | #define STATIC_ASSERT(e,m) ;enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(int)(!!(e)) } 369 | //#define STATIC_ASSERT(expr, msg) typedef char ASSERT_CONCAT(static_assert_check_, __LINE__) [(expr) ? (+1) : (-1)] 370 | 371 | #define _STRINGIFY(x) #x 372 | #define STR(x) _STRINGIFY(x) 373 | 374 | #define BIT(n) (1<<(n)) 375 | 376 | // ==== HW ID 377 | uint8_t get_hw_id(); 378 | 379 | // ==== RTC 380 | void rtc_read(tm_t * tm, dt_t *dt); 381 | void rtc_write(tm_t * tm, dt_t *dt); 382 | void rtc_update_time_sec(int delta_sec); 383 | uint8_t rtc_read_century(); 384 | void rtc_write_century(uint8_t cent); 385 | uint8_t rtc_read_min(); 386 | uint8_t rtc_read_sec(); 387 | void rtc_wakeup_delay(); 388 | 389 | // ==== VBAT 390 | uint32_t read_power_voltage(); 391 | int get_lowbat_state(); 392 | int get_vbat(); 393 | 394 | // ==== Buzzer 395 | // Freq in mHz 396 | void start_buzzer_freq(uint32_t freq); 397 | void stop_buzzer(); 398 | void set_buzzer(int pin1val, int pin2val); 399 | 400 | void beep_volume_up(); 401 | void beep_volume_down(); 402 | int get_beep_volume(); 403 | 404 | 405 | // ==== REGIONS 406 | uint32_t mark_region(uint32_t id); 407 | void no_region(); 408 | 409 | 410 | // ==== RESET values 411 | #define NO_SPLASH_MAGIC 0xEACE7362 412 | #define ALLOC_FAIL_MAGIC 0x363EACE7 413 | #define CLEAN_RESET_MAGIC 0x3EACE736 414 | #define RUN_DMCP_MAGIC 0x3CE7EA37 415 | 416 | void set_reset_magic(uint32_t value); 417 | 418 | 419 | 420 | // === RESET STATE FILE 421 | int is_reset_state_file(); 422 | char * get_reset_state_file(); 423 | void set_reset_state_file(const char * str); 424 | 425 | 426 | // ==== USB functions 427 | int switch_usb_powered_freq(); 428 | int usb_powered(); 429 | void usb_acm_on(); 430 | int usb_is_on(); 431 | void usb_turn_off(); 432 | void acm_puts(const char *str); 433 | 434 | // Aux buf 435 | #define AUX_BUF_SIZE (5*512) 436 | 437 | char * aux_buf_ptr(); 438 | void * write_buf_ptr(); 439 | int write_buf_size(); 440 | 441 | // Program info structure 442 | #define PROG_INFO_MAGIC 0xd377C0DE 443 | 444 | void program_main(); 445 | 446 | typedef struct { 447 | uint32_t pgm_magic; 448 | uint32_t pgm_size; 449 | void * pgm_entry; 450 | uint32_t ifc_cnr; 451 | uint32_t ifc_ver; 452 | uint32_t qspi_size; 453 | uint32_t qspi_crc; 454 | char pgm_name[16]; 455 | char pgm_ver[16]; 456 | uint32_t required_keymap_id; 457 | } __packed prog_info_t; 458 | 459 | 460 | // Keyboard 461 | int read_key(int *k1, int *k2); 462 | int sys_last_scan(int *k1, int *k2); 463 | 464 | ///////////////////////////////// 465 | // Low level diagnostics 466 | ///////////////////////////////// 467 | 468 | void suspended_bg_key_read(); 469 | void resume_bg_key_read(); 470 | 471 | // Timer 472 | uint32_t get_tim1_timer(); 473 | 474 | // Base frequency 8MHz 475 | #define TIMER_BASE_FREQ (8000000) 476 | void start_timer2(uint32_t div32); 477 | void start_timer3(uint16_t div16); 478 | void stop_timer2(); 479 | void stop_timer3(); 480 | 481 | // RTC linear reading 482 | #define RTCREGS_SS_PER_SEC 256 483 | 484 | typedef struct { 485 | uint32_t dt; 486 | uint32_t tm; 487 | uint16_t ss; 488 | } rtc_time_regs_t; 489 | 490 | 491 | typedef struct { 492 | rtc_time_regs_t regs; 493 | uint64_t dsec; // julian day * seconds_per_day 494 | uint32_t jday; // julian day 495 | uint32_t sec; // seconds in day 496 | uint32_t msec; // seconds in day corresponding to current minute (for easy sub-minute updates) 497 | } rtc_ticks_stat_t; 498 | 499 | 500 | uint32_t get_rtc_ticks(); 501 | rtc_ticks_stat_t* rtc_update_ticks(); 502 | void rtc_set_alarm(tm_t * tm, dt_t *dt); 503 | void rtc_cancel_alarm(); 504 | 505 | 506 | 507 | // QSPI User area 508 | int qspi_user_write(uint8_t *data, int size, int offset, int erase); 509 | uint8_t * qspi_user_addr(); 510 | int qspi_user_size(); 511 | 512 | 513 | // RESET preserved region 0x10007f00-0x10007fff (L4) 514 | #define RESET_STATE_RAM 0x10007f00 515 | 516 | 517 | 518 | // ---------------------------------- 519 | 520 | 521 | // Printer 522 | #define PRINT_GRA_LN 1 523 | #define PRINT_TXT_LN 0 524 | 525 | #define MAX_82240_WIDTH 166 526 | #define DFLT_82240_LINE_DUR 1800 527 | 528 | void print_byte(uint8_t b); 529 | void print_buffer(uint8_t * buf, int cnt); 530 | int print_is_ready(); 531 | 532 | // Printer delay in ms 533 | uint printer_get_delay(); 534 | void printer_set_delay(uint val); 535 | 536 | 537 | void printer_advance_buf(int what); 538 | int printer_busy_for(int what); 539 | 540 | 541 | // ---------------------------------- 542 | 543 | 544 | // -------------------------------- 545 | // Menu pages 546 | // -------------------------------- 547 | 548 | typedef void void_fn_t(); 549 | 550 | typedef struct { 551 | const char * name; 552 | const uint8_t * items; 553 | const char* const * msg; 554 | void_fn_t * post_disp; 555 | } smenu_t; 556 | 557 | extern const smenu_t MID_SYS_WARN; // System menu entry warning 558 | extern const smenu_t MID_SYSTEM; // System menu 559 | extern const smenu_t MID_FAT_FORMAT; // FAT format menu 560 | extern const smenu_t MID_DSKTST_ENTER; // Disk test menu 561 | extern const smenu_t MID_PROD_DIAG; // Production diagnostic screen 562 | extern const smenu_t MID_PROD_DIAG2; // Production diagnostic screen - selftest version in main menu 563 | extern const smenu_t MID_DMCP; // Top level system menu 564 | extern const smenu_t MID_BASE_SETUP; // System setup menu 565 | extern const smenu_t MID_BAD_KMAP; // Bad keymap menu 566 | 567 | 568 | // -------------------------------- 569 | // Menu items 570 | // app range 0-127 571 | // sys range 128-255 572 | // -------------------------------- 573 | 574 | #define MI_SYSTEM 192 575 | #define MI_BOOTLOADER 193 576 | #define MI_QSPI_LOADER 194 577 | #define MI_DIAG 195 578 | #define MI_MSC 196 579 | #define MI_ABOUT 197 580 | #define MI_BASE_SETUP 198 581 | #define MI_BEEP_MUTE 199 582 | #define MI_SYSTEM_ENTER 200 583 | #define MI_RELOAD_RESET 201 584 | #define MI_SET_TIME 202 585 | #define MI_SET_DATE 203 586 | #define MI_FF_ENTER 204 587 | #define MI_FAT_FORMAT 205 588 | #define MI_DISK_TEST 206 589 | #define MI_DSKTST_ENTER 207 590 | #define MI_DISK_INFO 208 591 | #define MI_LOAD_QSPI 209 592 | #define MI_SLOW_AUTOREP 210 593 | 594 | #define MI_EXIT 211 595 | 596 | #define MI_KBD_TEST 212 597 | #define MI_LCD_TEST 213 598 | #define MI_IR_TEST 214 599 | #define MI_BEEP_TEST 215 600 | #define MI_DMCP_MENU 216 601 | 602 | #define MI_SELF_TEST 217 603 | 604 | #define MI_RAMFLASH 218 605 | 606 | #define MI_PGM_INFO 219 607 | #define MI_PGM_RUN 220 608 | #define MI_PGM_LOAD 221 609 | 610 | #define MI_RUN_DMCP 222 611 | 612 | #define MI_OFF_MODE 223 613 | 614 | #define MI_KMAP_PGM_RUN 224 615 | #define MI_KMAP_DMCP 225 616 | 617 | // -------------------------------- 618 | 619 | 620 | 621 | #define MRET_LEAVELIMIT 512 622 | 623 | 624 | 625 | // -------------------------------- 626 | 627 | #define MENU_MAX_LEVEL 8 628 | 629 | #define MENU_FONT t24 630 | #define MENU_LCD_LINES 8 631 | 632 | #define MENU_RESET 0 633 | #define MENU_ADD 1 634 | 635 | #define MRET_UNIMPL -1 636 | #define MRET_EXIT -2 637 | 638 | // === Date/Time 639 | 640 | #define PRINT_DT_TM_SZ 20 641 | 642 | 643 | void rtc_check_unset(); 644 | void run_set_time(); 645 | void run_set_date(); 646 | 647 | 648 | // === Base dialogs 649 | void disp_disk_info(const char * hdr); 650 | int power_check_screen(); 651 | 652 | 653 | // === Base menu functions === 654 | int handle_menu(const smenu_t * menu_id, int action, int cur_line); 655 | 656 | // === Menu formatting support 657 | const char * rb_str(int val); 658 | const char * sel_str(int val); 659 | char * opt_str(char * s, char const *txt, int val); 660 | char * date_str(char * s, const char * txt); 661 | char * time_str(char * s, const char * txt); 662 | 663 | // === File selection === 664 | 665 | #define MAX_PGM_FN_LEN 24 666 | 667 | typedef int (*file_sel_fn_t)(const char * fpath, const char * fname, void * data); 668 | 669 | int file_selection_screen(const char * title, const char * base_dir, const char * ext, file_sel_fn_t sel_fn, 670 | int disp_new, int overwrite_check, void * data); 671 | 672 | 673 | 674 | 675 | // --------------------------------------------------- 676 | // Item selection screen 677 | // --------------------------------------------------- 678 | 679 | #define ISEL_FILL_ITEMS -100 680 | #define ISEL_KEY_PRESSED -101 681 | #define ISEL_EXIT -102 682 | 683 | #define ISEL_POST_DRAW -2 684 | #define ISEL_PRE_DRAW -1 685 | 686 | typedef uint16_t list_item_t; 687 | 688 | struct item_sel_state; 689 | typedef void isel_disp_line_fn_t(int lnr, list_item_t *fis, int cur_fnr, struct item_sel_state *st); 690 | typedef void fis_name_fn_t(struct item_sel_state *st, list_item_t fis, char * nmbuf, int len); 691 | 692 | 693 | typedef struct item_sel_state { 694 | int fnr; 695 | int top_nr; 696 | int8_t lncnt; // Number of LCD lines available 697 | int8_t roll_lines; 698 | int8_t key; 699 | 700 | list_item_t * fis; 701 | fis_name_fn_t * fis_name_fn; // Used for sorting 702 | int max_items; 703 | int fcnt; 704 | 705 | // -- Set by user -- 706 | const char * title; // Screen title 707 | char * title2; // Optional right part of title 708 | isel_disp_line_fn_t * disp_line_fn; // Line draw function 709 | char * lnbuf; // line buffer if app wants to use it for line drawing 710 | int lnsize; // lnbuf size 711 | 712 | void * data; // Custom data (useful for line draw callback) 713 | void * items; // Custom data for items 714 | 715 | } __packed item_sel_state_t; 716 | 717 | 718 | // Initialize item sel structure 719 | void item_sel_init(item_sel_state_t *st); 720 | void item_sel_reinit(item_sel_state_t *st); 721 | 722 | // upd == 1 -> force repaint 723 | int item_sel_engine(item_sel_state_t *st, int upd); 724 | 725 | // Display header 726 | void item_sel_header(item_sel_state_t *st, int update); 727 | 728 | // --------------------------------------------------- 729 | 730 | void msg_box(disp_stat_t * ds, const char * txt, int inv); 731 | 732 | 733 | int run_menu_item_sys(uint8_t line_id); 734 | 735 | 736 | // ---------------------------------- 737 | 738 | 739 | #define MAX_LCD_LINE_LEN 40 740 | 741 | #define MAX_KEY_NR 37 742 | #define MAX_FNKEY_NR 43 743 | 744 | 745 | // ------------- 746 | // Key codes 747 | // ------------- 748 | 749 | #define KEY_SIGMA 1 750 | #define KEY_INV 2 751 | #define KEY_SQRT 3 752 | #define KEY_LOG 4 753 | #define KEY_LN 5 754 | #define KEY_XEQ 6 755 | #define KEY_STO 7 756 | #define KEY_RCL 8 757 | #define KEY_RDN 9 758 | #define KEY_SIN 10 759 | #define KEY_COS 11 760 | #define KEY_TAN 12 761 | #define KEY_ENTER 13 762 | #define KEY_SWAP 14 763 | #define KEY_CHS 15 764 | #define KEY_E 16 765 | #define KEY_BSP 17 766 | #define KEY_UP 18 767 | #define KEY_7 19 768 | #define KEY_8 20 769 | #define KEY_9 21 770 | #define KEY_DIV 22 771 | #define KEY_DOWN 23 772 | #define KEY_4 24 773 | #define KEY_5 25 774 | #define KEY_6 26 775 | #define KEY_MUL 27 776 | #define KEY_SHIFT 28 777 | #define KEY_1 29 778 | #define KEY_2 30 779 | #define KEY_3 31 780 | #define KEY_SUB 32 781 | #define KEY_EXIT 33 782 | #define KEY_0 34 783 | #define KEY_DOT 35 784 | #define KEY_RUN 36 785 | #define KEY_ADD 37 786 | 787 | #define KEY_F1 38 788 | #define KEY_F2 39 789 | #define KEY_F3 40 790 | #define KEY_F4 41 791 | #define KEY_F5 42 792 | #define KEY_F6 43 793 | 794 | #define KEY_SCREENSHOT 44 795 | #define KEY_SH_UP 45 796 | #define KEY_SH_DOWN 46 797 | 798 | #define KEY_DOUBLE_RELEASE 99 799 | 800 | #define KEY_PAGEUP KEY_DIV 801 | #define KEY_PAGEDOWN KEY_MUL 802 | 803 | 804 | #define IS_EXIT_KEY(k) ( (k) == KEY_EXIT || (k) == KEY_BSP ) 805 | 806 | // ----------------------- 807 | // Bit masks operations 808 | // ----------------------- 809 | #define VAL(x,val) ((x) & (val)) 810 | #define CLR(x,val) val &= ~(x) 811 | #define SET(x,val) val |= (x) 812 | #define MSK(x,val) (~(x) & (val)) 813 | #define SETMSK(x,m,val) val = (MSK(m,val)|(x)) 814 | //#define SETBY(c,x,val) (c) ? SET(x,val) : CLR(x,val) 815 | #define SETBY(c,x,val) if (c) { SET(x,val); } else { CLR(x,val); } 816 | 817 | #define ST(x) VAL(x,calc_state) 818 | #define VAL_ST(x) VAL(x,calc_state) 819 | #define CLR_ST(x) CLR(x,calc_state) 820 | #define SET_ST(x) SET(x,calc_state) 821 | #define SETMSK_ST(x,m) SETMSK(x,m,calc_state) 822 | #define SETBY_ST(c,x) SETBY(c,x,calc_state) 823 | 824 | 825 | 826 | #define STAT_CLEAN_RESET BIT(0) 827 | #define STAT_RUNNING BIT(1) 828 | #define STAT_SUSPENDED BIT(2) 829 | #define STAT_KEYUP_WAIT BIT(3) 830 | #define STAT_OFF BIT(4) 831 | #define STAT_SOFT_OFF BIT(5) 832 | #define STAT_MENU BIT(6) 833 | #define STAT_BEEP_MUTE BIT(7) 834 | #define STAT_SLOW_AUTOREP BIT(8) 835 | #define STAT_PGM_END BIT(9) 836 | #define STAT_CLK_WKUP_ENABLE BIT(10) 837 | #define STAT_CLK_WKUP_SECONDS BIT(11) // 0 - wakeup runner each minute, 1 - each second 838 | #define STAT_CLK_WKUP_FLAG BIT(12) 839 | #define STAT_DMY BIT(13) 840 | #define STAT_CLK24 BIT(14) 841 | #define STAT_POWER_CHANGE BIT(15) 842 | #define STAT_YMD BIT(16) 843 | #define STAT_ALPHA_TAB_Fn BIT(17) // 1 - alpha table contains also Fn keys (First row) 844 | 845 | 846 | #define STAT_HW_BEEP BIT(28) 847 | #define STAT_HW_USB BIT(29) 848 | #define STAT_HW_IR BIT(30) 849 | 850 | #define STAT_HW (STAT_HW_BEEP | STAT_HW_USB | STAT_HW_IR) 851 | 852 | 853 | // Screenshots 854 | #define SCR_DIR "/SCREENS" 855 | 856 | // Power OFF images 857 | #define OFFIMG_DIR "/OFFIMG" 858 | 859 | // Help 860 | #define HELP_INDEX "/HELP/index.htm" 861 | #define HELP_DIR "/HELP" 862 | #define HELP_EXT_MASK "*.htm*" 863 | 864 | // Screenshot 865 | int create_screenshot(int report_error); 866 | 867 | 868 | // --------------------------- 869 | // Key buffer functions 870 | // --------------------------- 871 | int key_empty(); 872 | int key_push(int k1); 873 | int key_tail(); 874 | int key_pop(); 875 | int key_pop_last(); 876 | void key_pop_all(); 877 | 878 | 879 | // Key functions 880 | int key_to_nr(int key); 881 | void wait_for_key_press(); 882 | int runner_get_key(int *repeat); 883 | int runner_get_key_delay(int *repeat, uint timeout, uint rep0, uint rep1, uint rep1tout); 884 | void wait_for_key_release(int tout); 885 | 886 | 887 | 888 | // --------------------------- 889 | // Runner get key 890 | // --------------------------- 891 | 892 | int runner_key_tout_value(const int first); 893 | void runner_key_tout_init(const int slow); 894 | 895 | 896 | // Autorepeat 897 | int toggle_slow_autorepeat(); 898 | int is_slow_autorepeat(); 899 | 900 | // Auto off 901 | void reset_auto_off(); 902 | int is_auto_off(); 903 | int is_menu_auto_off(); 904 | int sys_auto_off_cnt(); 905 | 906 | // Time/date 907 | void print_dmy_date(char * s, int const sz, dt_t *dt, const char * append, int shortmon, char sep_arg); 908 | void print_clk24_time(char * t, int const sz, tm_t *tm, int disp_sec, int disp_dow); 909 | 910 | 911 | // Check and create dir 912 | // returns 0 on success 913 | int check_create_dir(const char * dir); 914 | 915 | // Set disk label 916 | void set_fat_label(const char * label); 917 | 918 | int file_exists(const char * fn); 919 | 920 | // Returns -1 if file doesn't exist 921 | int file_size(const char * fn); 922 | 923 | int sys_disk_ok(); 924 | int sys_disk_write_enable(int val); 925 | void sys_disk_check_valid(); 926 | int sys_is_disk_write_enable(); 927 | 928 | void sys_clear_write_buf_used(); 929 | int sys_write_buf_used(); 930 | 931 | 932 | // System timers 933 | void sys_timer_disable(int timer_ix); 934 | void sys_timer_start(int timer_ix, uint32_t ms_value); 935 | int sys_timer_active(int timer_ix); 936 | int sys_timer_timeout(int timer_ix); 937 | 938 | // Millisecond delay 939 | void sys_delay(uint32_t ms_delay); 940 | 941 | // Current systick count 942 | uint32_t sys_tick_count(); 943 | uint32_t sys_current_ms(); 944 | 945 | // Critical sections 946 | void sys_critical_start(); 947 | void sys_critical_end(); 948 | 949 | // Sleep 950 | void sys_sleep(); 951 | 952 | // Free memory 953 | int sys_free_mem(); 954 | int sys_largest_free_mem(); 955 | 956 | // System 957 | void sys_reset(); 958 | 959 | // Key 960 | int sys_last_key(); 961 | 962 | // Aux file 963 | void make_date_filename(char * str, const char * dir, const char * ext); 964 | 965 | 966 | // --------------------------- 967 | // Flashing 968 | // --------------------------- 969 | 970 | // Enable flashing 971 | void sys_flashing_init(); 972 | // Disable flashing 973 | void sys_flashing_finish(); 974 | 975 | // Expects address and size aligned with flash block size 976 | // Returns 0 on success 977 | int sys_flash_erase_block(void* start_addr, uint32_t size); 978 | 979 | // Expects destination address and size are multiples of 8 980 | // Returns 0 on success 981 | int sys_flash_write_block(void* dst_addr, uint8_t * src_buf, uint32_t size); 982 | 983 | 984 | // --------------------------- 985 | // QR code 986 | // --------------------------- 987 | 988 | void qrcode_disp(QRCode *qr, int xo, int yo, int z); 989 | 990 | 991 | // --------------------------- 992 | // System timers 993 | // --------------------------- 994 | 995 | #define SYSTIM_COUNT 4 996 | 997 | 998 | // ---------------------------------- 999 | 1000 | 1001 | void run_help(); 1002 | void run_help_file(const char * help_file); 1003 | 1004 | 1005 | 1006 | typedef void user_style_fn_t(char *s, disp_stat_t *ds); 1007 | 1008 | void run_help_file_style(const char * help_file, user_style_fn_t *user_style_fn); 1009 | 1010 | 1011 | // ---------------------------------- 1012 | 1013 | 1014 | // Off images 1015 | void draw_power_off_image(int allow_errors); 1016 | void reset_off_image_cycle(); 1017 | 1018 | #define BG_COL_PAPER 0xf4f2dc 1019 | #define BG_COL_LCD 0xdff5cc 1020 | 1021 | int update_bmp_file_header(FIL* fp, int width, int height, uint32_t bg_color); 1022 | 1023 | 1024 | // ---------------------------------- 1025 | 1026 | 1027 | #include "lft_ifc.h" 1028 | 1029 | #endif 1030 | --------------------------------------------------------------------------------