├── .gitignore ├── .gitmodules ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Doxyfile ├── LICENSE ├── Makefile ├── README.md ├── components ├── badge-first-run │ ├── Kconfig │ ├── badge_first_run.c │ ├── badge_first_run.h │ └── component.mk ├── badge │ ├── Kconfig │ ├── badge.c │ ├── badge.h │ ├── badge_base.c │ ├── badge_base.h │ ├── badge_button.h │ ├── badge_cpt112s.c │ ├── badge_cpt112s.h │ ├── badge_eink.c │ ├── badge_eink.h │ ├── badge_eink_dev.c │ ├── badge_eink_dev.h │ ├── badge_eink_fb.c │ ├── badge_eink_fb.h │ ├── badge_eink_lut.c │ ├── badge_eink_lut.h │ ├── badge_eink_types.h │ ├── badge_fxl6408.c │ ├── badge_fxl6408.h │ ├── badge_gpiobutton.c │ ├── badge_gpiobutton.h │ ├── badge_i2c.c │ ├── badge_i2c.h │ ├── badge_input.c │ ├── badge_input.h │ ├── badge_leds.c │ ├── badge_leds.h │ ├── badge_mpr121.c │ ├── badge_mpr121.h │ ├── badge_nvs.c │ ├── badge_nvs.h │ ├── badge_pins.h │ ├── badge_power.c │ ├── badge_power.h │ ├── badge_sdcard.c │ ├── badge_sdcard.h │ ├── badge_vibrator.c │ ├── badge_vibrator.h │ └── component.mk ├── bpp-if │ ├── Kconfig │ ├── bpp_init.c │ ├── bpp_init.h │ ├── bpp_sniffer.c │ ├── bpp_sniffer.h │ ├── bpp_udp.c │ ├── bpp_udp.h │ ├── component.mk │ ├── hexdump.c │ └── hexdump.h ├── bpp-recv │ ├── .gitignore │ ├── Makefile │ ├── bd_emu.c │ ├── bd_emu.h │ ├── bd_flatflash.c │ ├── bd_flatflash.h │ ├── bd_ropart.c │ ├── bd_ropart.h │ ├── bd_ropart_test │ ├── bd_ropart_test.c │ ├── blkidcache.h │ ├── blkidcache_mlvl.c │ ├── blkidcache_noop.c │ ├── blockdecode.c │ ├── blockdecode.h │ ├── blockdevif.h │ ├── bma.c │ ├── bma.h │ ├── chksign.h │ ├── chksign_ed25519.c │ ├── chksign_mbedtls.c │ ├── chksign_uecc.c │ ├── component.mk │ ├── crc16-ccitt.c │ ├── crc16-ccitt.h │ ├── defec.c │ ├── defec.h │ ├── defec_parity.c │ ├── defec_rs.c │ ├── hexdump.c │ ├── hexdump.h │ ├── hkpackets.c │ ├── hkpackets.h │ ├── hldemux.c │ ├── hldemux.h │ ├── main.c │ ├── mountbd.c │ ├── mountbd.h │ ├── partemu │ │ ├── esp_attr.h │ │ ├── esp_err.h │ │ ├── esp_partition.h │ │ ├── esp_spi_flash.h │ │ ├── esp_system.h │ │ ├── freertos │ │ │ ├── FreeRTOS.h │ │ │ ├── portmacro.h │ │ │ ├── queue.h │ │ │ ├── semphr.h │ │ │ └── timers.h │ │ └── partemu.c │ ├── powerdown.c │ ├── powerdown.h │ ├── pubkey.inc │ ├── recvif.h │ ├── serdec.c │ ├── serdec.h │ ├── structs.h │ ├── subtitle.c │ ├── subtitle.h │ └── tout ├── ed25519 │ ├── add_scalar.c │ ├── component.mk │ ├── ed25519.h │ ├── fe.c │ ├── fe.h │ ├── fixedint.h │ ├── ge.c │ ├── ge.h │ ├── include │ │ └── ed25519.h │ ├── key_exchange.c │ ├── keypair.c │ ├── precomp_data.h │ ├── sc.c │ ├── sc.h │ ├── seed.c │ ├── sha512.c │ ├── sha512.h │ ├── sign.c │ └── verify.c ├── graph │ ├── component.mk │ ├── font.c │ ├── font.h │ ├── font_16px.c │ ├── font_16px.h │ ├── font_8px.c │ └── font_8px.h ├── png │ ├── adler32.c │ ├── adler32.h │ ├── component.mk │ ├── crc32.c │ ├── crc32.h │ ├── deflate_reader.c │ ├── deflate_reader.h │ ├── file_reader.c │ ├── file_reader.h │ ├── flash_reader.c │ ├── flash_reader.h │ ├── mem_reader.c │ ├── mem_reader.h │ ├── png_reader.c │ ├── png_reader.h │ └── reader.h ├── redundancy │ ├── component.mk │ ├── redundancy.c │ └── redundancy.h ├── sha2017 │ ├── GeoTrust_Global_CA.der │ ├── GeoTrust_Global_CA.pem │ ├── Kconfig │ ├── component.mk │ ├── sha2017_ota.c │ ├── sha2017_ota.h │ ├── sha2017_ota_graphics.c │ ├── sha2017_ota_graphics.h │ ├── wildcard_sha2017_org.c │ └── wildcard_sha2017_org.h └── ugfx-glue │ ├── Kconfig │ ├── PermanentMarker.ttf │ ├── Roboto-Black.ttf │ ├── Roboto-BlackItalic.ttf │ ├── Roboto-Regular.ttf │ ├── board_framebuffer.h │ ├── build_fonts.sh │ ├── component.mk │ ├── crunch_fonts.sh │ ├── fonts │ ├── DejaVuSans20.c │ ├── PermanentMarker22.c │ ├── PermanentMarker36.c │ ├── Roboto-Black22.c │ ├── Roboto-BlackItalic24.c │ ├── Roboto-Regular12.c │ ├── Roboto-Regular18.c │ ├── Roboto-Regular22.c │ ├── pixelade13.c │ └── weather42.c │ ├── gdisp_lld_framebuffer.c │ ├── gfx_mk.c │ ├── gfx_userfs.c │ ├── gfx_userfs.h │ ├── gfxconf.h │ ├── ginput_lld_toggle.c │ ├── ginput_lld_toggle_config.h │ └── userfonts.h ├── main ├── Kconfig.projbuild ├── component.mk ├── demo_dot1.c ├── demo_dot1.h ├── demo_greyscale1.c ├── demo_greyscale1.h ├── demo_greyscale2.c ├── demo_greyscale2.h ├── demo_greyscale_img1.c ├── demo_greyscale_img1.h ├── demo_greyscale_img2.c ├── demo_greyscale_img2.h ├── demo_greyscale_img3.c ├── demo_greyscale_img3.h ├── demo_greyscale_img4.c ├── demo_greyscale_img4.h ├── demo_leds.c ├── demo_leds.h ├── demo_mpr121.c ├── demo_mpr121.h ├── demo_partial_update.c ├── demo_partial_update.h ├── demo_power.c ├── demo_power.h ├── demo_sdcard_image.c ├── demo_sdcard_image.h ├── demo_test_adc.c ├── demo_test_adc.h ├── demo_text1.c ├── demo_text1.h ├── demo_text2.c ├── demo_text2.h ├── demo_ugfx.c ├── demo_ugfx.h ├── img_hacking.c ├── img_hacking.h ├── imgv2_hacking.c ├── imgv2_hacking.h ├── imgv2_menu.c ├── imgv2_menu.h ├── imgv2_nick.c ├── imgv2_nick.h ├── imgv2_sha.c ├── imgv2_sha.h ├── imgv2_test.c ├── imgv2_test.h ├── imgv2_weather.c ├── imgv2_weather.h ├── leaseweb.c ├── leaseweb.h ├── madison_gurkha.c ├── madison_gurkha.h └── main.c ├── partitions-16MB.csv ├── partitions-4MB.csv ├── pictures ├── font_16px.png ├── font_8px.png ├── hacking.png ├── pic_1.png ├── pic_2.png ├── pic_3.jpg ├── pic_3.png ├── pic_4.png └── pic_5.png ├── sdkconfig.defaults ├── set_env.sh └── tools ├── font2h.pl ├── gen_fonts_h ├── gen_pictures_h ├── graphLUT.pl ├── png_to_c_v2.pl └── raw2h.pl /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | sdkconfig* 3 | makeenv 4 | custom_env.sh 5 | doxygen/ 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "esp-idf"] 2 | path = esp-idf 3 | url = https://github.com/SHA2017-badge/esp-idf.git 4 | branch = master 5 | [submodule "micropython"] 6 | path = micropython 7 | url = https://github.com/SHA2017-badge/micropython-esp32.git 8 | branch = master 9 | [submodule "ugfx"] 10 | path = ugfx 11 | url = https://github.com/SHA2017-badge/ugfx.git 12 | branch = master 13 | [submodule "micropython-lib"] 14 | path = micropython-lib 15 | url = https://github.com/SHA2017-badge/micropython-lib.git 16 | branch = master 17 | [submodule "examples"] 18 | path = examples 19 | url = https://github.com/SHA2017-badge/micropython-examples-sha2017.git 20 | branch = master 21 | [submodule "auto-flasher"] 22 | path = auto-flasher 23 | url = https://github.com/SHA2017-badge/auto-flasher.git 24 | [submodule "xtensa-esp32-elf"] 25 | path = xtensa-esp32-elf 26 | url = https://github.com/SHA2017-badge/xtensa-esp32-elf.git 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | sudo: false 3 | language: bash 4 | os: 5 | - linux 6 | 7 | addons: 8 | apt: 9 | packages: 10 | - gperf 11 | - python 12 | - python-serial 13 | - libffi-dev 14 | - libsdl2-dev 15 | - gcc-4.8-plugin-dev 16 | 17 | before_install: 18 | # Save path to the git respository 19 | - PROJECT_PATH=$(pwd) 20 | 21 | install: 22 | # Install ESP32 toochain following steps as desribed 23 | # in http://esp-idf.readthedocs.io/en/latest/linux-setup.html 24 | # 25 | # Get required packages - already done above, see addons: apt: packages: 26 | # - sudo apt-get install git wget make libncurses-dev flex bison gperf python python-serial 27 | # Prepare directory for the toolchain 28 | git submodule update --init --recursive 29 | 30 | script: 31 | - pip install pyserial 32 | # Update configuration so that kconfig doesn't start interactive mode 33 | - make --version 34 | - du -hs 35 | - source set_env.sh 36 | - make defconfig 37 | # Build project from the git repository 38 | - make -j3 39 | # Build the micropython firmware 40 | - make -j3 -C micropython/esp32 41 | # Build micropython unix 'badge emulator' 42 | - git clone https://github.com/ARMmbed/mbedtls.git micropython/lib/mbedtls 43 | - make -j3 -C micropython/lib/mbedtls 44 | - make -j3 -C micropython/unix 45 | - du -hs 46 | 47 | notifications: 48 | irc: 49 | channels: 50 | - "chat.freenode.net#sha2017-badge" 51 | - "chat.freenode.net#sha2017-badge-dev" 52 | on_success: change 53 | on_failure: always 54 | use_notice: true 55 | skip_join: true 56 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | We warmly welcome contributions. New versions of the badge firmware are 2 | distributed periodically to all users on the field through OTA updates. While 3 | availability of OTA updates is prominently broadcasted and they are easy for 4 | users to install, they are not mandatory. 5 | 6 | All contributions must be licensed under Apache License 2.0 unless explicitly 7 | stated otherwise. 8 | 9 | # Testing 10 | 11 | Both branches and PR's are tested on 12 | [Travis](https://travis-ci.org/SHA2017-badge). Note that due to the nature of 13 | the project there travis only compiles the project, there is no extensive test 14 | suite - so careful reviewing and testing remains vitally important. 15 | 16 | # Reviewing 17 | 18 | All pull requests must be reviewed by at least 1 team member before merging, 19 | and preferably tested on a real badge. 20 | 21 | # Working with submodules 22 | 23 | We make extensive use of submodules. While this makes it much easier for 24 | participants to check out and build a consistent version of the software, it 25 | introduces some room for error when accepting contributions. To minimize this 26 | risk we use the following workflow when contributing changes that touch 27 | submodules: 28 | 29 | * create a branch in the submodule 30 | * make changes 31 | * push and PR to `master` of this submodule 32 | * merge after reviewing the PR 33 | * then only after that is merged: 34 | * create a branch in the main module 35 | * change the submodule reference to point to the new submodule master 36 | * make any other changes to the main project as needed 37 | * push and PR to `master` of the main module 38 | * merge after Travis is green and the PR is reviewed 39 | 40 | There are 2 special cases to this workflow: 41 | 42 | 1 if the PR to `master` contains no other changes except the updated reference 43 | to the submodule, it can be merged without further review as soon as Travis is green. After all, the change has been reviewed when merging the PR to the submodule. 44 | 2 For complex changes it may be useful to temporarily point a branch in the main module to a branch of the submodule. This should be prominently mentioned in any PR though, and these should be merged in the following order: 45 | 46 | * merge the PR in the submodule 47 | * update the PR in the main module to point to the (new) master of the submodule 48 | * merge the PR in the main module 49 | 50 | This may seem convoluted, but helps avoid mistakes with pointers to unmerged 51 | branches of submodules or pointers to branches of submodules that are merged 52 | but don't have all (other) commits that are on the submodule master. 53 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This is a project Makefile. It is assumed the directory this Makefile resides in is a 3 | # project subdirectory. 4 | # 5 | 6 | PROJECT_NAME := sha2017-badge-test 7 | 8 | ifndef PROJECT_PATH 9 | PROJECT_PATH := $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) 10 | export PROJECT_PATH 11 | endif 12 | 13 | ifndef IDF_PATH 14 | IDF_PATH := $(PROJECT_PATH)/esp-idf 15 | export IDF_PATH 16 | endif 17 | 18 | UGFX_PATH := $(PROJECT_PATH)/ugfx 19 | export UGFX_PATH 20 | 21 | include $(IDF_PATH)/make/project.mk 22 | -------------------------------------------------------------------------------- /components/badge-first-run/Kconfig: -------------------------------------------------------------------------------- 1 | menu "SHA2017 Badge First Run" 2 | 3 | config DEBUG_ADD_DELAYS 4 | bool "debug -- add delays" 5 | default n 6 | help 7 | Add delays to make all output readable. 8 | 9 | config BASVS_BROKEN_BADGE 10 | bool "debug -- basvs broken badge" 11 | default n 12 | help 13 | One of my badges has a non-functioning SELECT button. 14 | Am using this config-option to avoid building final images 15 | with workarounds for it. 16 | 17 | You probably don't want this, unless you're using my badge. 18 | 19 | config ALLOW_BATTERY_FIRST_BOOT 20 | bool "Allow battery present during first boot sequence" 21 | default n 22 | help 23 | If enabled the first run will not stop when battery voltage is detected, useful for developing 24 | 25 | endmenu 26 | -------------------------------------------------------------------------------- /components/badge-first-run/badge_first_run.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPONENTS_BADGE_FIRST_RUN_BADGE_FIRST_RUN_H 2 | #define COMPONENTS_BADGE_FIRST_RUN_BADGE_FIRST_RUN_H 3 | 4 | extern void badge_check_first_run(void); 5 | extern void badge_first_run(void); 6 | 7 | #endif // COMPONENTS_BADGE_FIRST_RUN_BADGE_FIRST_RUN_H 8 | -------------------------------------------------------------------------------- /components/badge-first-run/component.mk: -------------------------------------------------------------------------------- 1 | # Component Makefile 2 | 3 | COMPONENT_ADD_INCLUDEDIRS := . 4 | 5 | -------------------------------------------------------------------------------- /components/badge/Kconfig: -------------------------------------------------------------------------------- 1 | menu "SHA2017 Badge" 2 | 3 | choice SHA_BADGE_REV 4 | prompt "SHA Badge revision" 5 | default SHA_BADGE_V3 6 | help 7 | This option sets the SHA badge revision. 8 | 9 | - Rev1.0.0 Dev: Release candidate 10 | (may 2017) 11 | - Rev1.0.0 Dev without the MPR121 chip. 12 | - Rev0.1.0 Dev: Improved badge. 13 | (february 2017) 14 | - Rev0.0.1 Dev: The original development badge. 15 | (december 2016) 16 | - Plain ESP32 hardware 17 | 18 | config SHA_BADGE_V3 19 | bool "Rev1.0.*" 20 | config SHA_BADGE_V3_LITE 21 | bool "Rev1.0.* (without mpr121)" 22 | config SHA_BADGE_V2 23 | bool "Rev0.1.0 Dev" 24 | config SHA_BADGE_V1 25 | bool "Rev0.0.1 Dev" 26 | config SHA_BADGE_NONE 27 | bool "Plain ESP32" 28 | endchoice 29 | 30 | choice SHA_BADGE_EINK_DEFAULT_TYPE 31 | prompt "SHA Badge e-ink default display type" 32 | default SHA_BADGE_EINK_DEF_DEPG0290B1 33 | depends on SHA_BADGE_V1 || SHA_BADGE_V2 || SHA_BADGE_V3 || SHA_BADGE_V3_LITE 34 | help 35 | The DEPG0290B1 is the cheaper alternative. 36 | The GDEH029A1 was the original e-ink display. 37 | 38 | config SHA_BADGE_EINK_DEF_DEPG0290B1 39 | bool "DEPG0290B1" 40 | config SHA_BADGE_EINK_DEF_GDEH029A1 41 | bool "GDEH029A1" 42 | endchoice 43 | 44 | config SHA_BADGE_LEDS_WS2812 45 | bool "Using WS2812 LEDS instead of SK6812" 46 | depends on SHA_BADGE_V2 || SHA_BADGE_V3 || SHA_BADGE_V3_LITE 47 | default n 48 | help 49 | On earlier developer boards, WS2812 leds were used 50 | instead of SK6812. This option modifies the data 51 | stream to emulate the SK6812 LEDS. 52 | 53 | config SHA_BADGE_INPUT_DEBUG 54 | bool "Enable input debug messages" 55 | default n 56 | help 57 | Debugging 58 | 59 | config SHA_BADGE_FXL6408_DEBUG 60 | bool "Enable FXL6408 port-expander debug messages" 61 | depends on SHA_BADGE_V2 62 | default n 63 | help 64 | Debugging 65 | 66 | config SHA_BADGE_CPT112S_DEBUG 67 | bool "Enable CPT112S debug messages" 68 | depends on SHA_BADGE_V2 69 | default n 70 | help 71 | Debugging 72 | 73 | config SHA_BADGE_MPR121_DEBUG 74 | bool "Enable MPR121 debug messages" 75 | depends on SHA_BADGE_V3 76 | default n 77 | help 78 | Debugging 79 | 80 | config SHA_BADGE_MPR121_HARDCODE_BASELINE 81 | bool "Enable MPR121 hardcoded baseline values" 82 | depends on SHA_BADGE_V3 83 | default y 84 | help 85 | The baseline data was tested on one specific badge. Other badges 86 | might need different baselines. Disable this to use automatic 87 | base-line detection. (can cause buttons to not respond) 88 | 89 | config SHA_BADGE_EINK_DEBUG 90 | bool "Enable eink debug messages" 91 | depends on SHA_BADGE_V1 || SHA_BADGE_V2 || SHA_BADGE_V3 || SHA_BADGE_V3_LITE 92 | default n 93 | help 94 | Debugging 95 | 96 | config SHA_BADGE_EINK_LUT_DEBUG 97 | bool "Enable eink lookup-table debug messages" 98 | depends on SHA_BADGE_V1 || SHA_BADGE_V2 || SHA_BADGE_V3 || SHA_BADGE_V3_LITE 99 | default n 100 | help 101 | Debugging 102 | 103 | config SHA_BADGE_POWER_DEBUG 104 | bool "Enable power/charging debug messages" 105 | depends on SHA_BADGE_V1 || SHA_BADGE_V2 || SHA_BADGE_V3 || SHA_BADGE_V3_LITE 106 | default n 107 | help 108 | Debugging 109 | 110 | endmenu 111 | -------------------------------------------------------------------------------- /components/badge/badge.h: -------------------------------------------------------------------------------- 1 | /** @file badge.h */ 2 | #ifndef BADGE_H 3 | #define BADGE_H 4 | 5 | __BEGIN_DECLS 6 | 7 | /** 8 | * Initialize all badge drivers. 9 | */ 10 | extern void badge_init(void); 11 | 12 | __END_DECLS 13 | 14 | #endif // BADGE_H 15 | -------------------------------------------------------------------------------- /components/badge/badge_base.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "badge_base.h" 9 | 10 | static const char *TAG = "badge_base"; 11 | 12 | esp_err_t 13 | badge_base_init(void) 14 | { 15 | static bool badge_base_init_done = false; 16 | 17 | if (badge_base_init_done) 18 | return ESP_OK; 19 | 20 | ESP_LOGD(TAG, "init called"); 21 | 22 | // install isr-service, so we can register interrupt-handlers per 23 | // gpio pin. 24 | esp_err_t res = gpio_install_isr_service(0); 25 | if (res == ESP_FAIL) 26 | { 27 | ESP_LOGW(TAG, "Failed to install gpio isr service. Ignoring this."); 28 | res = ESP_OK; 29 | } 30 | 31 | if (res != ESP_OK) 32 | { 33 | ESP_LOGE(TAG, "Failed to install gpio isr service: %d", res); 34 | return res; 35 | } 36 | 37 | badge_base_init_done = true; 38 | 39 | ESP_LOGD(TAG, "init done"); 40 | 41 | return ESP_OK; 42 | } 43 | -------------------------------------------------------------------------------- /components/badge/badge_base.h: -------------------------------------------------------------------------------- 1 | /** @file badge_base.h */ 2 | #ifndef BADGE_BASE_H 3 | #define BADGE_BASE_H 4 | 5 | #include 6 | 7 | __BEGIN_DECLS 8 | 9 | /** 10 | * Initialize badge base driver. 11 | * @return ESP_OK on success; any other value indicates an error 12 | */ 13 | extern esp_err_t badge_base_init(void); 14 | 15 | __END_DECLS 16 | 17 | #endif // BADGE_BASE_H 18 | -------------------------------------------------------------------------------- /components/badge/badge_button.h: -------------------------------------------------------------------------------- 1 | /** @file badge_button.h */ 2 | #ifndef BADGE_BUTTON_H 3 | #define BADGE_BUTTON_H 4 | 5 | /** badge button constants */ 6 | enum badge_button_t { 7 | BADGE_BUTTON_UP = 1, 8 | BADGE_BUTTON_DOWN = 2, 9 | BADGE_BUTTON_LEFT = 3, 10 | BADGE_BUTTON_RIGHT = 4, 11 | 12 | BADGE_BUTTON_A = 6, 13 | BADGE_BUTTON_B = 7, 14 | BADGE_BUTTON_SELECT = 8, 15 | BADGE_BUTTON_START = 9, 16 | BADGE_BUTTON_FLASH = 10, 17 | 18 | // Number of buttons on the badge 19 | BADGE_BUTTONS = 10, 20 | }; 21 | 22 | #endif // BADGE_BUTTON_H 23 | -------------------------------------------------------------------------------- /components/badge/badge_cpt112s.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef CONFIG_SHA_BADGE_CPT112S_DEBUG 4 | #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG 5 | #endif // CONFIG_SHA_BADGE_CPT112S_DEBUG 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #ifdef I2C_CPT112S_ADDR 20 | 21 | static const char *TAG = "badge_cpt112s"; 22 | 23 | badge_cpt112s_event_t badge_cpt112s_handler = NULL; 24 | 25 | static inline int 26 | badge_cpt112s_read_event(void) 27 | { 28 | uint8_t buf[3]; 29 | esp_err_t ret = badge_i2c_read_event(I2C_CPT112S_ADDR, buf); 30 | 31 | if (ret == ESP_OK) { 32 | ESP_LOGD(TAG, "event: 0x%02x, 0x%02x, 0x%02x", buf[0], buf[1], buf[2]); 33 | return (buf[0] << 16) | (buf[1] << 8) | (buf[2]); 34 | } else { 35 | ESP_LOGE(TAG, "i2c master read: error %d", ret); 36 | return -1; 37 | } 38 | } 39 | 40 | void 41 | badge_cpt112s_intr_handler(void *arg) 42 | { 43 | while (1) 44 | { 45 | // read cpt112s-controller interrupt line 46 | int x = badge_fxl6408_get_input(); 47 | if (x == -1) // error 48 | continue; // retry.. 49 | 50 | if (x & (1 << FXL6408_PIN_NUM_CPT112S)) // no events waiting 51 | break; 52 | 53 | // event waiting 54 | int event = badge_cpt112s_read_event(); 55 | 56 | if (event == -1) // error 57 | continue; 58 | 59 | if (badge_cpt112s_handler != NULL) 60 | badge_cpt112s_handler(event); 61 | } 62 | } 63 | 64 | esp_err_t 65 | badge_cpt112s_init(void) 66 | { 67 | static bool badge_cpt112s_init_done = false; 68 | 69 | if (badge_cpt112s_init_done) 70 | return ESP_OK; 71 | 72 | ESP_LOGD(TAG, "init called"); 73 | 74 | badge_fxl6408_set_interrupt_handler(FXL6408_PIN_NUM_CPT112S, badge_cpt112s_intr_handler, NULL); 75 | 76 | esp_err_t res; 77 | res = badge_fxl6408_init(); 78 | if (res != ESP_OK) 79 | return res; 80 | res = badge_fxl6408_set_input_default_state(FXL6408_PIN_NUM_CPT112S, 1); 81 | if (res != ESP_OK) 82 | return res; 83 | res = badge_fxl6408_set_interrupt_enable(FXL6408_PIN_NUM_CPT112S, 1); 84 | if (res != ESP_OK) 85 | return res; 86 | 87 | // read pending old events 88 | badge_cpt112s_intr_handler(NULL); 89 | 90 | badge_cpt112s_init_done = true; 91 | 92 | ESP_LOGD(TAG, "init done"); 93 | 94 | return ESP_OK; 95 | } 96 | 97 | void 98 | badge_cpt112s_set_event_handler(badge_cpt112s_event_t handler) 99 | { 100 | badge_cpt112s_handler = handler; 101 | } 102 | 103 | #endif // I2C_CPT112S_ADDR 104 | -------------------------------------------------------------------------------- /components/badge/badge_cpt112s.h: -------------------------------------------------------------------------------- 1 | /** @file badge_cpt112s.h */ 2 | #ifndef BADGE_CPT112S_H 3 | #define BADGE_CPT112S_H 4 | 5 | #include 6 | 7 | /** callback handler for cpt112s events */ 8 | typedef void (*badge_cpt112s_event_t)(int event); 9 | 10 | __BEGIN_DECLS 11 | 12 | /** initialize the badge cpt112s controller 13 | * @return ESP_OK on success; any other value indicates an error 14 | */ 15 | extern esp_err_t badge_cpt112s_init(void); 16 | 17 | /** set the cpt112s-event callback method 18 | * @param handler the handler to install 19 | * @note It is safe to set the event handler before a call to badge_cpt112s_init(). 20 | */ 21 | extern void badge_cpt112s_set_event_handler(badge_cpt112s_event_t handler); 22 | 23 | __END_DECLS 24 | 25 | #endif // BADGE_CPT112S_H 26 | -------------------------------------------------------------------------------- /components/badge/badge_eink_dev.h: -------------------------------------------------------------------------------- 1 | /** @file badge_eink_dev.h */ 2 | #ifndef BADGE_EINK_DEV_H 3 | #define BADGE_EINK_DEV_H 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | /** the number of horizontal pixels 12 | * @note the display is rotated 90 degrees 13 | */ 14 | #define DISP_SIZE_X 128 15 | 16 | /** the number of vertical pixels 17 | * @note the display is rotated 90 degrees 18 | */ 19 | #define DISP_SIZE_Y 296 20 | 21 | /** the number of bytes in a pixel row 22 | * @note the display is rotated 90 degrees 23 | */ 24 | #define DISP_SIZE_X_B ((DISP_SIZE_X + 7) >> 3) 25 | 26 | /** the currently initialized display type */ 27 | extern enum badge_eink_dev_t badge_eink_dev_type; 28 | 29 | __BEGIN_DECLS 30 | 31 | /** Initialize the SPI bus to the eink display. 32 | * @return ESP_OK on success; any other value indicates an error 33 | */ 34 | extern esp_err_t badge_eink_dev_init(enum badge_eink_dev_t dev_type); 35 | 36 | /** Send reset to the device 37 | * @return ESP_OK on success; any other value indicates an error 38 | */ 39 | extern esp_err_t badge_eink_dev_reset(void); 40 | 41 | /** returns the busy-status of the eink-display 42 | * @return the status 43 | */ 44 | extern bool badge_eink_dev_is_busy(void); 45 | 46 | /** wait for display to become ready 47 | */ 48 | extern void badge_eink_dev_busy_wait(void); 49 | 50 | /** write an spi data byte to the display 51 | * @param data the byte to write 52 | */ 53 | extern void badge_eink_dev_write_byte(uint8_t data); 54 | 55 | /** write an spi command byte to the display (without any data bytes) 56 | * @param command the byte to write 57 | */ 58 | extern void badge_eink_dev_write_command(uint8_t command); 59 | 60 | /** helper method: write command with 1 parameter */ 61 | static inline void badge_eink_dev_write_command_p1(uint8_t command, uint8_t para1) 62 | { 63 | badge_eink_dev_write_command(command); 64 | badge_eink_dev_write_byte(para1); 65 | } 66 | 67 | /** helper method: write command with 2 parameters */ 68 | static inline void badge_eink_dev_write_command_p2(uint8_t command, uint8_t para1, 69 | uint8_t para2) 70 | { 71 | badge_eink_dev_write_command(command); 72 | badge_eink_dev_write_byte(para1); 73 | badge_eink_dev_write_byte(para2); 74 | } 75 | 76 | /** helper method: write command with 3 parameters */ 77 | static inline void badge_eink_dev_write_command_p3(uint8_t command, uint8_t para1, 78 | uint8_t para2, uint8_t para3) 79 | { 80 | badge_eink_dev_write_command(command); 81 | badge_eink_dev_write_byte(para1); 82 | badge_eink_dev_write_byte(para2); 83 | badge_eink_dev_write_byte(para3); 84 | } 85 | 86 | /** helper method: write command with 4 parameters */ 87 | static inline void badge_eink_dev_write_command_p4(uint8_t command, uint8_t para1, 88 | uint8_t para2, uint8_t para3, 89 | uint8_t para4) 90 | { 91 | badge_eink_dev_write_command(command); 92 | badge_eink_dev_write_byte(para1); 93 | badge_eink_dev_write_byte(para2); 94 | badge_eink_dev_write_byte(para3); 95 | badge_eink_dev_write_byte(para4); 96 | } 97 | 98 | /** write command with `datalen` data bytes */ 99 | void badge_eink_dev_write_command_stream(uint8_t command, const uint8_t *data, 100 | unsigned int datalen); 101 | 102 | /** write command with `datalen` data dwords */ 103 | void badge_eink_dev_write_command_stream_u32(uint8_t command, const uint32_t *data, 104 | unsigned int datalen); 105 | 106 | __END_DECLS 107 | 108 | #endif // BADGE_EINK_DEV_H 109 | -------------------------------------------------------------------------------- /components/badge/badge_eink_fb.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include "badge_eink_fb.h" 11 | 12 | static const char *TAG = "badge_eink_fb"; 13 | 14 | uint8_t *badge_eink_fb = NULL; 15 | 16 | esp_err_t 17 | badge_eink_fb_init(void) 18 | { 19 | if (badge_eink_fb) 20 | return ESP_OK; 21 | 22 | ESP_LOGD(TAG, "init called"); 23 | 24 | badge_eink_fb = (uint8_t *) malloc(BADGE_EINK_FB_LEN); 25 | if (badge_eink_fb == NULL) 26 | return ESP_ERR_NO_MEM; 27 | 28 | ESP_LOGD(TAG, "init done"); 29 | 30 | return ESP_OK; 31 | } 32 | -------------------------------------------------------------------------------- /components/badge/badge_eink_fb.h: -------------------------------------------------------------------------------- 1 | /** @file badge_eink_fb.h */ 2 | #ifndef BADGE_EINK_FB_H 3 | #define BADGE_EINK_FB_H 4 | 5 | #include 6 | #include 7 | 8 | #include "badge_eink.h" 9 | 10 | __BEGIN_DECLS 11 | 12 | /** the size of the badge_eink_fb buffer */ 13 | #define BADGE_EINK_FB_LEN (BADGE_EINK_WIDTH * BADGE_EINK_HEIGHT) 14 | 15 | /** A one byte per pixel frame-buffer */ 16 | extern uint8_t *badge_eink_fb; 17 | 18 | /** 19 | * Initialize badge eink framebuffer. 20 | * @return ESP_OK on success; any other value indicates an error 21 | */ 22 | extern esp_err_t badge_eink_fb_init(void); 23 | 24 | __END_DECLS 25 | 26 | #endif // BADGE_EINK_FB_H 27 | -------------------------------------------------------------------------------- /components/badge/badge_eink_lut.h: -------------------------------------------------------------------------------- 1 | /** @file badge_eink_lut.h */ 2 | #ifndef BADGE_EINK_LUT_H 3 | #define BADGE_EINK_LUT_H 4 | 5 | #include 6 | 7 | /** the needed size of the buffer used in badge_eink_generate_lut() */ 8 | #define BADGE_EINK_LUT_MAX_SIZE 70 9 | 10 | /** specification of display update instruction */ 11 | struct badge_eink_lut_entry { 12 | /** the number of cycles the voltages are held; 0 = end of list */ 13 | uint8_t length; 14 | 15 | /** bitmapped value containing voltages for every (old-bit, new-bit) pair: 16 | * - bits 0,1: from 0 to 0 17 | * - bits 2,3: from 0 to 1 18 | * - bits 4,5: from 1 to 0 19 | * - bits 6,7: from 1 to 1 20 | * 21 | * allowed values: 22 | * - 0: VSS 23 | * - 1: VSH 24 | * - 2: VSL 25 | */ 26 | uint8_t voltages; 27 | }; 28 | 29 | /** filters to use on a badge_eink_lut_entry structure */ 30 | enum badge_eink_lut_flags { 31 | LUT_FLAG_FIRST = 1, // do not depend on previous image 32 | LUT_FLAG_PARTIAL = 2, // do not touch already correct pixels 33 | LUT_FLAG_WHITE = 4, // white only 34 | LUT_FLAG_BLACK = 8, // black only 35 | }; 36 | 37 | __BEGIN_DECLS 38 | 39 | /** 40 | * Generate LUT data for specific eink display. 41 | * 42 | * @param list screen updata data in 'generic' format. 43 | * @param flags optional alterations on generated lut data. 44 | * @param lut output data buffer. should be of size BADGE_EINK_LUT_MAX_SIZE. 45 | * @return lut length. returns -1 on error. 46 | */ 47 | extern int badge_eink_lut_generate(const struct badge_eink_lut_entry *list, enum badge_eink_lut_flags flags, uint8_t *lut); 48 | 49 | /* pre-defined lookup-table display-updates. */ 50 | 51 | /** full screen update with inverse updates */ 52 | extern const struct badge_eink_lut_entry badge_eink_lut_full[]; 53 | /** screen update which just sets the black and white */ 54 | extern const struct badge_eink_lut_entry badge_eink_lut_normal[]; 55 | /** same as badge_eink_lut_normal but with shorter timings */ 56 | extern const struct badge_eink_lut_entry badge_eink_lut_faster[]; 57 | /** same as badge_eink_lut_faster but with shorter timings */ 58 | extern const struct badge_eink_lut_entry badge_eink_lut_fastest[]; 59 | 60 | __END_DECLS 61 | 62 | #endif // BADGE_EINK_LUT_H 63 | -------------------------------------------------------------------------------- /components/badge/badge_eink_types.h: -------------------------------------------------------------------------------- 1 | /** @file badge_eink_types.h */ 2 | #ifndef BADGE_EINK_TYPES_H 3 | #define BADGE_EINK_TYPES_H 4 | 5 | #include 6 | 7 | /** 8 | * Badge eink types. 9 | */ 10 | /* NOTE: This value is used in nvs. Do not change order or remove elements. */ 11 | enum badge_eink_dev_t { 12 | BADGE_EINK_NONE, 13 | BADGE_EINK_GDEH029A1, 14 | BADGE_EINK_DEPG0290B1, 15 | }; 16 | 17 | /** 18 | * BADGE_EINK_DEFAULT specifies the compile-time default display type 19 | */ 20 | #if defined(CONFIG_SHA_BADGE_EINK_DEF_DEPG0290B1) 21 | #define BADGE_EINK_DEFAULT BADGE_EINK_DEPG0290B1 22 | #elif defined(CONFIG_SHA_BADGE_EINK_DEF_GDEH029A1) 23 | #define BADGE_EINK_DEFAULT BADGE_EINK_GDEH029A1 24 | #else 25 | #define BADGE_EINK_DEFAULT BADGE_EINK_NONE 26 | #endif 27 | 28 | #endif // BADGE_EINK_TYPES_H 29 | -------------------------------------------------------------------------------- /components/badge/badge_fxl6408.h: -------------------------------------------------------------------------------- 1 | /** @file badge_fxl6408.h */ 2 | #ifndef BADGE_FXL6408_H 3 | #define BADGE_FXL6408_H 4 | 5 | #include 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | /** port-expander interrupt handler */ 11 | typedef void (*badge_fxl6408_intr_t)(void*); 12 | 13 | /** initialize port-expander 14 | * @return ESP_OK on success; any other value indicates an error 15 | */ 16 | extern esp_err_t badge_fxl6408_init(void); 17 | 18 | /** configure port-expander gpio port - io direction */ 19 | extern esp_err_t badge_fxl6408_set_io_direction(uint8_t pin, uint8_t direction); 20 | /** configure port-expander gpio port - output state */ 21 | extern esp_err_t badge_fxl6408_set_output_state(uint8_t pin, uint8_t state); 22 | /** configure port-expander gpio port - output high-z */ 23 | extern esp_err_t badge_fxl6408_set_output_high_z(uint8_t pin, uint8_t high_z); 24 | /** configure port-expander gpio port - input default state */ 25 | extern esp_err_t badge_fxl6408_set_input_default_state(uint8_t pin, uint8_t state); 26 | /** configure port-expander gpio port - pull enable */ 27 | extern esp_err_t badge_fxl6408_set_pull_enable(uint8_t pin, uint8_t enable); 28 | /** configure port-expander gpio port - pull down/up */ 29 | extern esp_err_t badge_fxl6408_set_pull_down_up(uint8_t pin, uint8_t up); 30 | /** configure port-expander gpio port - interrupt enable/disable */ 31 | extern esp_err_t badge_fxl6408_set_interrupt_enable(uint8_t pin, uint8_t enable); 32 | /** configure port-expander gpio port - set interrupt callback method */ 33 | extern void badge_fxl6408_set_interrupt_handler(uint8_t pin, badge_fxl6408_intr_t handler, void *arg); 34 | 35 | /** configure port-expander gpio port - get input status */ 36 | extern int badge_fxl6408_get_input(void); 37 | /** configure port-expander gpio port - get interrupt status */ 38 | extern int badge_fxl6408_get_interrupt_status(void); 39 | 40 | __END_DECLS 41 | 42 | #endif // BADGE_FXL6408_H 43 | -------------------------------------------------------------------------------- /components/badge/badge_gpiobutton.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "badge_base.h" 7 | #include "badge_input.h" 8 | #include "badge_gpiobutton.h" 9 | 10 | static const char *TAG = "badge_gpiobutton"; 11 | 12 | uint32_t badge_gpiobutton_conv[40] = { 0 }; 13 | int badge_gpiobutton_old_state[40] = { 0 }; 14 | 15 | void 16 | badge_gpiobutton_handler(void *arg) 17 | { /* in interrupt handler */ 18 | uint32_t gpio_num = (uint32_t) arg; 19 | 20 | int new_state = gpio_get_level(gpio_num); 21 | if (new_state != badge_gpiobutton_old_state[gpio_num]) 22 | { 23 | uint32_t button_id = badge_gpiobutton_conv[gpio_num]; 24 | badge_input_add_event(button_id, new_state == 0 ? EVENT_BUTTON_PRESSED : EVENT_BUTTON_RELEASED, IN_ISR); 25 | } 26 | badge_gpiobutton_old_state[gpio_num] = new_state; 27 | } 28 | 29 | esp_err_t 30 | badge_gpiobutton_add(int gpio_num, uint32_t button_id) 31 | { 32 | esp_err_t res = badge_base_init(); 33 | if (res != ESP_OK) 34 | return res; 35 | 36 | ESP_LOGD(TAG, "add button called"); 37 | 38 | badge_gpiobutton_conv[gpio_num] = button_id; 39 | badge_gpiobutton_old_state[gpio_num] = 1; // released 40 | 41 | res = gpio_isr_handler_add(gpio_num, badge_gpiobutton_handler, (void*) gpio_num); 42 | if (res != ESP_OK) 43 | return res; 44 | 45 | // configure the gpio pin for input 46 | gpio_config_t io_conf = { 47 | .intr_type = GPIO_INTR_ANYEDGE, 48 | .mode = GPIO_MODE_INPUT, 49 | .pin_bit_mask = 1LL << gpio_num, 50 | .pull_down_en = 0, 51 | .pull_up_en = 1, 52 | }; 53 | res = gpio_config(&io_conf); 54 | if (res != ESP_OK) 55 | return res; 56 | 57 | ESP_LOGD(TAG, "add button done"); 58 | 59 | return res; 60 | } 61 | -------------------------------------------------------------------------------- /components/badge/badge_gpiobutton.h: -------------------------------------------------------------------------------- 1 | /** @file badge_gpiobutton.h */ 2 | #ifndef BADGE_GPIOBUTTON_H 3 | #define BADGE_GPIOBUTTON_H 4 | 5 | #include 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | /** configure gpio pin as button 11 | * @return ESP_OK on success; any other value indicates an error 12 | */ 13 | extern esp_err_t badge_gpiobutton_add(int gpio_num, uint32_t button_id); 14 | 15 | __END_DECLS 16 | 17 | #endif // BADGE_GPIOBUTTON_H 18 | -------------------------------------------------------------------------------- /components/badge/badge_i2c.h: -------------------------------------------------------------------------------- 1 | /** @file badge_i2c.h */ 2 | #ifndef BADGE_I2C_H 3 | #define BADGE_I2C_H 4 | 5 | #include 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | /** initialize i2c bus 11 | * @return ESP_OK on success; any other value indicates an error 12 | */ 13 | extern esp_err_t badge_i2c_init(void); 14 | 15 | /** read register via i2c bus 16 | * @return ESP_OK on success; any other value indicates an error 17 | */ 18 | extern esp_err_t badge_i2c_read_reg(uint8_t addr, uint8_t reg, uint8_t *value, size_t value_len); 19 | 20 | /** write to register via i2c bus 21 | * @return ESP_OK on success; any other value indicates an error 22 | */ 23 | extern esp_err_t badge_i2c_write_reg(uint8_t addr, uint8_t reg, uint8_t value); 24 | 25 | /** read event via i2c bus 26 | * @return ESP_OK on success; any other value indicates an error 27 | */ 28 | extern esp_err_t badge_i2c_read_event(uint8_t addr, uint8_t *buf); 29 | 30 | __END_DECLS 31 | 32 | #endif // BADGE_I2C_H 33 | -------------------------------------------------------------------------------- /components/badge/badge_input.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef CONFIG_SHA_BADGE_INPUT_DEBUG 4 | #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG 5 | #endif // CONFIG_SHA_BADGE_INPUT_DEBUG 6 | 7 | #include 8 | #include 9 | 10 | #include "badge_input.h" 11 | 12 | static const char *TAG = "badge_input"; 13 | 14 | xQueueHandle badge_input_queue = NULL; 15 | void (*badge_input_notify)(void); 16 | uint32_t badge_input_button_state = 0; 17 | 18 | esp_err_t 19 | badge_input_init(void) 20 | { 21 | static bool badge_input_init_done = false; 22 | 23 | if (badge_input_init_done) 24 | return ESP_OK; 25 | 26 | ESP_LOGD(TAG, "init called"); 27 | 28 | badge_input_queue = xQueueCreate(10, sizeof(uint32_t)); 29 | if (badge_input_queue == NULL) 30 | return ESP_ERR_NO_MEM; 31 | 32 | badge_input_init_done = true; 33 | 34 | ESP_LOGD(TAG, "init done"); 35 | 36 | return ESP_OK; 37 | } 38 | 39 | #ifdef CONFIG_SHA_BADGE_INPUT_DEBUG 40 | static const char *badge_input_button_name[11] = { 41 | "(null)", 42 | "UP", 43 | "DOWN", 44 | "LEFT", 45 | "RIGHT", 46 | "(null)", 47 | "A", 48 | "B", 49 | "SELECT", 50 | "START", 51 | "FLASH", 52 | }; 53 | #endif // CONFIG_SHA_BADGE_INPUT_DEBUG 54 | 55 | void 56 | badge_input_add_event(uint32_t button_id, bool pressed, bool in_isr) 57 | { /* maybe in interrupt handler */ 58 | #ifdef CONFIG_SHA_BADGE_INPUT_DEBUG 59 | ets_printf("badge_input: Button %s %s.\n", 60 | badge_input_button_name[button_id < 11 ? button_id : 0], 61 | pressed ? "pressed" : "released"); 62 | #endif // CONFIG_SHA_BADGE_INPUT_DEBUG 63 | 64 | if (pressed) 65 | { 66 | badge_input_button_state |= 1 << button_id; 67 | if (in_isr) 68 | { 69 | if (xQueueSendFromISR(badge_input_queue, &button_id, NULL) != pdTRUE) 70 | { 71 | ets_printf("badge_input: input queue full.\n"); 72 | } 73 | } 74 | else 75 | { 76 | if (xQueueSend(badge_input_queue, &button_id, 0) != pdTRUE) 77 | { 78 | ets_printf("badge_input: input queue full.\n"); 79 | } 80 | } 81 | } 82 | else 83 | { 84 | badge_input_button_state &= ~(1 << button_id); 85 | } 86 | 87 | if (badge_input_notify != NULL) 88 | badge_input_notify(); 89 | } 90 | 91 | uint32_t 92 | badge_input_get_event(int timeout) 93 | { 94 | int xqueuetimeout = (timeout == -1) ? portMAX_DELAY : timeout / portTICK_RATE_MS; 95 | uint32_t button_id; 96 | if (xQueueReceive(badge_input_queue, &button_id, xqueuetimeout)) { 97 | return button_id; 98 | } 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /components/badge/badge_input.h: -------------------------------------------------------------------------------- 1 | /** @file badge_input.h */ 2 | #ifndef BADGE_INPUT_H 3 | #define BADGE_INPUT_H 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | __BEGIN_DECLS 10 | 11 | /** initialize badge input 12 | * @return ESP_OK on success; any other value indicates an error 13 | */ 14 | extern esp_err_t badge_input_init(void); 15 | 16 | /** button is released */ 17 | #define EVENT_BUTTON_RELEASED false 18 | /** button is pressed */ 19 | #define EVENT_BUTTON_PRESSED true 20 | /** calling from outside ISR */ 21 | #define NOT_IN_ISR false 22 | /** calling from inside ISR */ 23 | #define IN_ISR true 24 | /** add event to input queue */ 25 | extern void badge_input_add_event(uint32_t button_id, bool pressed, bool in_isr); 26 | 27 | /** retrieve button input 28 | * @param timeout the timeout in milliseconds; use -1 for infinite wait 29 | * @return button_id is button is pressed; 0 if timeout is reached 30 | */ 31 | extern uint32_t badge_input_get_event(int timeout); 32 | 33 | /** badge input button state (bitmap of all buttons) 34 | * If bit is 0, then button is not pressed, if 1, button is pressed. 35 | */ 36 | extern uint32_t badge_input_button_state; 37 | 38 | /** callback method to get notifies on events. */ 39 | extern void (*badge_input_notify)(void); 40 | 41 | __END_DECLS 42 | 43 | #endif // BADGE_INPUT_H 44 | -------------------------------------------------------------------------------- /components/badge/badge_leds.h: -------------------------------------------------------------------------------- 1 | /** @file badge_leds.h */ 2 | #ifndef BADGE_LEDS_H 3 | #define BADGE_LEDS_H 4 | 5 | #include 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | /** 11 | * Initialize the leds driver. (configure SPI bus and GPIO pins) 12 | * @return ESP_OK on success; any other value indicates an error 13 | */ 14 | extern esp_err_t badge_leds_init(void); 15 | 16 | /** 17 | * Enable power to the leds bar. 18 | * @return ESP_OK on success; any other value indicates an error 19 | */ 20 | extern esp_err_t badge_leds_enable(void); 21 | 22 | /** 23 | * Disable power to the leds bar. 24 | * @return ESP_OK on success; any other value indicates an error 25 | */ 26 | extern esp_err_t badge_leds_disable(void); 27 | 28 | /** 29 | * Send color-data to the leds bus. 30 | * @param data the data-bytes to send on the bus. 31 | * @param len the data-length. 32 | * @note The first 6 leds on the bus are probably SK6812RGBW leds. 33 | * SK6812RGBW expects 4 bytes per led: green, red, blue and white. 34 | * @return ESP_OK on success; any other value indicates an error 35 | */ 36 | extern esp_err_t badge_leds_send_data(uint8_t *data, int len); 37 | 38 | __END_DECLS 39 | 40 | #endif // BADGE_LEDS_H 41 | -------------------------------------------------------------------------------- /components/badge/badge_nvs.h: -------------------------------------------------------------------------------- 1 | /** @file badge_nvs.h */ 2 | #ifndef BADGE_NVS_H 3 | #define BADGE_NVS_H 4 | 5 | #include 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | /** 11 | * Initialize the nvs driver. 12 | * @return ESP_OK on success; any other value indicates an error 13 | */ 14 | extern esp_err_t badge_nvs_init(void); 15 | 16 | /** 17 | * Erase a page from namespace 18 | * @return ESP_OK on success; any other value indicates an error 19 | */ 20 | extern esp_err_t badge_nvs_erase_all(const char* namespace); 21 | 22 | /** 23 | * Erase a value from namespace, key 24 | * @return ESP_OK on success; any other value indicates an error 25 | */ 26 | extern esp_err_t badge_nvs_erase_key(const char* namespace, const char* key); 27 | 28 | /** 29 | * Get an uint8 value from namespace, key 30 | * @return ESP_OK on success; any other value indicates an error 31 | */ 32 | extern esp_err_t badge_nvs_get_u8(const char* namespace, const char* key, uint8_t *value); 33 | 34 | /** 35 | * Set an uint8 value in namespace, key 36 | * @return ESP_OK on success; any other value indicates an error 37 | */ 38 | extern esp_err_t badge_nvs_set_u8(const char* namespace, const char* key, uint8_t value); 39 | 40 | /** 41 | * Get an uint16 value from namespace, key 42 | * @return ESP_OK on success; any other value indicates an error 43 | */ 44 | extern esp_err_t badge_nvs_get_u16(const char* namespace, const char* key, uint16_t *value); 45 | 46 | /** 47 | * Set an uint16 value in namespace, key 48 | * @return ESP_OK on success; any other value indicates an error 49 | */ 50 | extern esp_err_t badge_nvs_set_u16(const char* namespace, const char* key, uint16_t value); 51 | 52 | /** 53 | * Get a string value from namespace, key 54 | * @return ESP_OK on success; any other value indicates an error 55 | */ 56 | extern esp_err_t badge_nvs_get_str(const char* namespace, const char* key, char *value, size_t *length); 57 | 58 | /** 59 | * Set a string value in namespace, key 60 | * @return ESP_OK on success; any other value indicates an error 61 | */ 62 | extern esp_err_t badge_nvs_set_str(const char* namespace, const char* key, const char *value); 63 | 64 | __END_DECLS 65 | 66 | #endif // BADGE_NVS_H 67 | -------------------------------------------------------------------------------- /components/badge/badge_power.h: -------------------------------------------------------------------------------- 1 | /** @file badge_power.h */ 2 | #ifndef BADGE_POWER_H 3 | #define BADGE_POWER_H 4 | 5 | #include 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | /** 11 | * initializes the battery and usb power sensing 12 | * @return ESP_OK on success; any other value indicates an error 13 | */ 14 | extern esp_err_t badge_power_init(void); 15 | 16 | /** 17 | * returns the charging state. 18 | * 19 | * @return true if charging; false otherwise. 20 | */ 21 | extern bool badge_battery_charge_status(void); 22 | 23 | /** 24 | * returns the Vbat voltage. 25 | * 26 | * @return Vbat voltage in mV; -1 on error 27 | */ 28 | extern int badge_battery_volt_sense(void); 29 | 30 | /** 31 | * returns the Vusb voltage. 32 | * 33 | * @return Vusb voltage in mV; -1 on error 34 | */ 35 | extern int badge_usb_volt_sense(void); 36 | 37 | /** 38 | * enable power to the leds-bar 39 | * 40 | * @return ESP_OK on success; any other value indicates an error 41 | */ 42 | extern esp_err_t badge_power_leds_enable(void); 43 | 44 | /** 45 | * disable power to the leds-bar 46 | * 47 | * @return ESP_OK on success; any other value indicates an error 48 | * @note shared resource: if the power to the sd-card is also enabled, 49 | * the power will stay on. 50 | */ 51 | extern esp_err_t badge_power_leds_disable(void); 52 | 53 | /** 54 | * enable power to the sd-card 55 | * 56 | * @return ESP_OK on success; any other value indicates an error 57 | */ 58 | extern esp_err_t badge_power_sdcard_enable(void); 59 | 60 | /** 61 | * disable power to the sd-card 62 | * 63 | * @return ESP_OK on success; any other value indicates an error 64 | * @note shared resource: if the power to the leds-bar is also enabled, 65 | * the power will stay on. 66 | */ 67 | extern esp_err_t badge_power_sdcard_disable(void); 68 | 69 | __END_DECLS 70 | 71 | #endif // BADGE_POWER_H 72 | -------------------------------------------------------------------------------- /components/badge/badge_sdcard.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "badge_pins.h" 11 | #include "badge_fxl6408.h" 12 | #include "badge_mpr121.h" 13 | #include "badge_sdcard.h" 14 | 15 | static const char *TAG = "badge_sdcard"; 16 | 17 | #if defined(FXL6408_PIN_NUM_SD_CD) || defined(MPR121_PIN_NUM_SD_CD) 18 | bool 19 | badge_sdcard_detected(void) 20 | { 21 | #ifdef FXL6408_PIN_NUM_SD_CD 22 | return (badge_fxl6408_get_input() >> FXL6408_PIN_NUM_SD_CD) & 1; 23 | #elif defined(MPR121_PIN_NUM_SD_CD) 24 | return badge_mpr121_get_gpio_level(MPR121_PIN_NUM_SD_CD); 25 | #endif 26 | } 27 | #endif // defined(FXL6408_PIN_NUM_SD_CD) || defined(MPR121_PIN_NUM_SD_CD) 28 | 29 | esp_err_t 30 | badge_sdcard_init(void) 31 | { 32 | static bool badge_sdcard_init_done = false; 33 | esp_err_t res; 34 | 35 | if (badge_sdcard_init_done) 36 | return ESP_OK; 37 | 38 | ESP_LOGD(TAG, "init called"); 39 | 40 | // configure charge-stat pin 41 | #ifdef FXL6408_PIN_NUM_SD_CD 42 | res = badge_fxl6408_init(); 43 | if (res != ESP_OK) 44 | return res; 45 | res = badge_fxl6408_set_io_direction(FXL6408_PIN_NUM_SD_CD, 0); 46 | if (res != ESP_OK) 47 | return res; 48 | res = badge_fxl6408_set_input_default_state(FXL6408_PIN_NUM_SD_CD, 0); 49 | if (res != ESP_OK) 50 | return res; 51 | res = badge_fxl6408_set_pull_enable(FXL6408_PIN_NUM_SD_CD, 0); 52 | if (res != ESP_OK) 53 | return res; 54 | res = badge_fxl6408_set_interrupt_enable(FXL6408_PIN_NUM_SD_CD, 0); 55 | if (res != ESP_OK) 56 | return res; 57 | #elif defined(MPR121_PIN_NUM_SD_CD) 58 | res = badge_mpr121_init(); 59 | if (res != ESP_OK) 60 | return res; 61 | res = badge_mpr121_configure_gpio(MPR121_PIN_NUM_SD_CD, MPR121_INPUT); 62 | if (res != ESP_OK) 63 | return res; 64 | #endif 65 | 66 | badge_sdcard_init_done = true; 67 | 68 | ESP_LOGD(TAG, "init done"); 69 | 70 | return ESP_OK; 71 | } 72 | -------------------------------------------------------------------------------- /components/badge/badge_sdcard.h: -------------------------------------------------------------------------------- 1 | /** @file badge_sdcard.h */ 2 | #ifndef BADGE_SDCARD_H 3 | #define BADGE_SDCARD_H 4 | 5 | #include 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | /** initialize the sdcard inserted sensor 11 | * @return ESP_OK on success; any other value indicates an error 12 | */ 13 | extern esp_err_t badge_sdcard_init(void); 14 | 15 | /** report if an sdcard is inserted */ 16 | extern bool badge_sdcard_detected(void); 17 | 18 | __END_DECLS 19 | 20 | #endif // BADGE_SDCARD_H 21 | -------------------------------------------------------------------------------- /components/badge/badge_vibrator.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "badge_pins.h" 15 | #include "badge_i2c.h" 16 | #include "badge_fxl6408.h" 17 | #include "badge_mpr121.h" 18 | #include "badge_vibrator.h" 19 | 20 | static const char *TAG = "badge_vibrator"; 21 | 22 | #if defined(FXL6408_PIN_NUM_VIBRATOR) || defined(MPR121_PIN_NUM_VIBRATOR) 23 | 24 | static int 25 | badge_vibrator_on(void) 26 | { 27 | #ifdef FXL6408_PIN_NUM_VIBRATOR 28 | return badge_fxl6408_set_output_state(FXL6408_PIN_NUM_VIBRATOR, 1); 29 | #elif defined(MPR121_PIN_NUM_VIBRATOR) 30 | return badge_mpr121_set_gpio_level(MPR121_PIN_NUM_VIBRATOR, 1); 31 | #endif 32 | } 33 | 34 | static int 35 | badge_vibrator_off(void) 36 | { 37 | #ifdef FXL6408_PIN_NUM_VIBRATOR 38 | return badge_fxl6408_set_output_state(FXL6408_PIN_NUM_VIBRATOR, 0); 39 | #elif defined(MPR121_PIN_NUM_VIBRATOR) 40 | return badge_mpr121_set_gpio_level(MPR121_PIN_NUM_VIBRATOR, 0); 41 | #endif 42 | } 43 | 44 | void 45 | badge_vibrator_activate(uint32_t pattern) 46 | { 47 | while (pattern != 0) 48 | { 49 | if ((pattern & 1) == 0) 50 | badge_vibrator_off(); 51 | else 52 | badge_vibrator_on(); 53 | pattern >>= 1; 54 | ets_delay_us(200000); 55 | } 56 | badge_vibrator_off(); 57 | } 58 | 59 | esp_err_t 60 | badge_vibrator_init(void) 61 | { 62 | static bool badge_vibrator_init_done = false; 63 | esp_err_t res; 64 | 65 | if (badge_vibrator_init_done) 66 | return ESP_OK; 67 | 68 | ESP_LOGD(TAG, "init called"); 69 | 70 | // configure vibrator pin 71 | #ifdef FXL6408_PIN_NUM_VIBRATOR 72 | res = badge_fxl6408_init(); 73 | if (res != ESP_OK) 74 | return res; 75 | res = badge_fxl6408_set_output_state(FXL6408_PIN_NUM_VIBRATOR, 0); 76 | if (res != ESP_OK) 77 | return res; 78 | res = badge_fxl6408_set_output_high_z(FXL6408_PIN_NUM_VIBRATOR, 0); 79 | if (res != ESP_OK) 80 | return res; 81 | res = badge_fxl6408_set_io_direction(FXL6408_PIN_NUM_VIBRATOR, 1); 82 | if (res != ESP_OK) 83 | return res; 84 | #elif defined(MPR121_PIN_NUM_VIBRATOR) 85 | res = badge_mpr121_init(); 86 | if (res != ESP_OK) 87 | return res; 88 | res = badge_mpr121_configure_gpio(MPR121_PIN_NUM_VIBRATOR, MPR121_OUTPUT); 89 | if (res != ESP_OK) 90 | return res; 91 | #endif 92 | 93 | badge_vibrator_init_done = true; 94 | 95 | ESP_LOGD(TAG, "init done"); 96 | 97 | return ESP_OK; 98 | } 99 | 100 | #endif // defined(FXL6408_PIN_NUM_VIBRATOR) || defined(MPR121_PIN_NUM_VIBRATOR) 101 | -------------------------------------------------------------------------------- /components/badge/badge_vibrator.h: -------------------------------------------------------------------------------- 1 | /** @file badge_vibrator.h */ 2 | #ifndef BADGE_VIBRATOR_H 3 | #define BADGE_VIBRATOR_H 4 | 5 | #include 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | /** 11 | * Initialize vibrator driver. (GPIO ports) 12 | * @return ESP_OK on success; any other value indicates an error 13 | */ 14 | extern esp_err_t badge_vibrator_init(void); 15 | 16 | /** 17 | * Send bit-pattern to the vibrator. 18 | * @note Every bit takes approx. 200ms. Lowest bit is used first. 19 | * 20 | * Code example: 21 | * 22 | * badge_vibrator_activate(0xd); 23 | * // vibrator will be on for 200ms. Then off for 200ms. Then on for 400ms. 24 | */ 25 | extern void badge_vibrator_activate(uint32_t pattern); 26 | 27 | __END_DECLS 28 | 29 | #endif // BADGE_VIBRATOR_H 30 | -------------------------------------------------------------------------------- /components/badge/component.mk: -------------------------------------------------------------------------------- 1 | # Component Makefile 2 | 3 | COMPONENT_ADD_INCLUDEDIRS := . 4 | 5 | -------------------------------------------------------------------------------- /components/bpp-if/Kconfig: -------------------------------------------------------------------------------- 1 | menu "SHA2017 BPP" 2 | 3 | config SHA_BPP_ENABLE 4 | bool "Enable BPP" 5 | default y 6 | help 7 | Enable passive firmware and read-only filesystem updates 8 | 9 | endmenu 10 | -------------------------------------------------------------------------------- /components/bpp-if/bpp_init.h: -------------------------------------------------------------------------------- 1 | #ifndef BPP_INIT_H 2 | #define BPP_INIT_H 3 | 4 | void bpp_mount_ropart(); 5 | void bpp_init(void); 6 | void bpp_shutdown(); 7 | 8 | #endif -------------------------------------------------------------------------------- /components/bpp-if/bpp_sniffer.h: -------------------------------------------------------------------------------- 1 | #ifndef BPP_SNIFFER_H 2 | #define BPP_SNIFFER_H 3 | 4 | void bppWifiSnifferStart(); 5 | 6 | #endif -------------------------------------------------------------------------------- /components/bpp-if/bpp_udp.h: -------------------------------------------------------------------------------- 1 | #ifndef BPP_UDP_H 2 | #define BPP_UDP_H 3 | 4 | void bppConnectUsingUdp(const char *ssid, const char *server, int port, int powerHandle); 5 | 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /components/bpp-if/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Component Makefile 3 | # 4 | 5 | 6 | COMPONENT_ADD_INCLUDEDIRS := . 7 | 8 | -------------------------------------------------------------------------------- /components/bpp-if/hexdump.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void hexdump (void *addr, int len) { 6 | int i; 7 | unsigned char buff[17]; 8 | unsigned char *pc = (unsigned char*)addr; 9 | 10 | 11 | if (len == 0) { 12 | printf(" ZERO LENGTH\n"); 13 | return; 14 | } 15 | if (len < 0) { 16 | printf(" NEGATIVE LENGTH: %i\n",len); 17 | return; 18 | } 19 | 20 | // Process every byte in the data. 21 | for (i = 0; i < len; i++) { 22 | // Multiple of 16 means new line (with line offset). 23 | 24 | if ((i % 16) == 0) { 25 | // Just don't print ASCII for the zeroth line. 26 | if (i != 0) 27 | printf (" %s\n", buff); 28 | 29 | // Output the offset. 30 | printf (" %04x ", i); 31 | } 32 | 33 | // Now the hex code for the specific character. 34 | printf (" %02x", pc[i]); 35 | 36 | // And store a printable ASCII character for later. 37 | if ((pc[i] < 0x20) || (pc[i] > 0x7e)) 38 | buff[i % 16] = '.'; 39 | else 40 | buff[i % 16] = pc[i]; 41 | buff[(i % 16) + 1] = '\0'; 42 | } 43 | 44 | // Pad out last line if not exactly 16 characters. 45 | while ((i % 16) != 0) { 46 | printf (" "); 47 | i++; 48 | } 49 | 50 | // And print the final ASCII bit. 51 | printf (" %s\n", buff); 52 | } 53 | -------------------------------------------------------------------------------- /components/bpp-if/hexdump.h: -------------------------------------------------------------------------------- 1 | void hexdump (void *addr, int len); 2 | 3 | -------------------------------------------------------------------------------- /components/bpp-recv/.gitignore: -------------------------------------------------------------------------------- 1 | part-*.img 2 | tst/ 3 | *.o 4 | recv 5 | -------------------------------------------------------------------------------- /components/bpp-recv/Makefile: -------------------------------------------------------------------------------- 1 | #Makefile for a host build of the receiver. 2 | 3 | OBJS=main.o chksign_ed25519.o defec.o serdec.o hexdump.o subtitle.o hldemux.o \ 4 | bd_emu.o blockdecode.o blkidcache_mlvl.o partemu/partemu.o bd_flatflash.o \ 5 | hkpackets.o powerdown.o defec_rs.o defec_parity.o bma.o ../redundancy/redundancy.o \ 6 | bd_ropart.o 7 | OBJS+=../ed25519/add_scalar.o ../ed25519/fe.o ../ed25519/ge.o ../ed25519/key_exchange.o \ 8 | ../ed25519/keypair.o ../ed25519/sc.o ../ed25519/seed.o ../ed25519/sha512.o \ 9 | ../ed25519/sign.o ../ed25519/verify.o 10 | TARGET=recv 11 | CFLAGS=-ggdb -I ../common -I ../micro-ecc -I ../ed25519 -I partemu \ 12 | -Og -DHOST_BUILD -I../redundancy 13 | LDFLAGS=-lmbedtls -lmbedcrypto 14 | 15 | all: $(TARGET) 16 | 17 | sha256.o: ../sha256/sha256.c ../sha256/sha256.h 18 | $(CC) $(CFLAGS) -c -o $@ $< 19 | 20 | uECC.o: ../micro-ecc/uECC.c ../micro-ecc/uECC.h 21 | $(CC) $(CFLAGS) -c -o $@ $< 22 | 23 | $(TARGET): $(OBJS) 24 | $(CC) -o $@ $^ $(LDFLAGS) 25 | 26 | clean: 27 | rm -f $(OBJS) $(TARGET) 28 | 29 | test: bd_ropart_test 30 | 31 | bd_ropart_test: bd_ropart.o bd_ropart_test.o partemu/partemu.o blkidcache_mlvl.o bma.o 32 | $(CC) -o $@ $^ $(LDFLAGS) 33 | -------------------------------------------------------------------------------- /components/bpp-recv/bd_emu.c: -------------------------------------------------------------------------------- 1 | /* 2 | Host-side blockdev emulation. 3 | 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "structs.h" 16 | #include "blockdevif.h" 17 | #include "bd_emu.h" 18 | 19 | struct BlockdevifHandle { 20 | int size; 21 | int bdFd, idFd; 22 | uint8_t *bdData; 23 | uint32_t *idData; 24 | }; 25 | 26 | static BlockdevifHandle *blockdevifInit(void *desc, int size) { 27 | BlockdevIfBdemuDesc *bdesc=(BlockdevIfBdemuDesc*)desc; 28 | char buf[1024]; 29 | BlockdevifHandle *h=malloc(sizeof(BlockdevifHandle)); 30 | h->size=size; 31 | h->bdFd=open(bdesc->file, O_RDWR|O_CREAT, 0644); 32 | if (h->bdFd<=0){ 33 | printf("opening bdev:\n"); 34 | perror(bdesc->file); 35 | goto error1; 36 | } 37 | ftruncate(h->bdFd, size); 38 | sprintf(buf, "%s.ids", bdesc->file); 39 | h->idFd=open(buf, O_RDWR|O_CREAT, 0644); 40 | if (h->idFd<=0){ 41 | printf("opening bdev idfile:\n"); 42 | perror(buf); 43 | goto error2; 44 | } 45 | ftruncate(h->idFd, (size/BLOCKDEV_BLKSZ)*sizeof(uint32_t)); 46 | h->bdData=mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, h->bdFd, 0); 47 | if (h->bdData==MAP_FAILED) { 48 | printf("mmap bdev:\n"); 49 | perror(bdesc->file); 50 | goto error3; 51 | } 52 | h->idData=mmap(NULL, (size/BLOCKDEV_BLKSZ)*sizeof(uint32_t), PROT_READ|PROT_WRITE, MAP_SHARED, h->idFd, 0); 53 | if (h->idData==MAP_FAILED) { 54 | printf("mmap bdev idfile:\n"); 55 | perror(buf); 56 | goto error4; 57 | } 58 | return h; 59 | 60 | error4: 61 | munmap(h->bdData, size); 62 | error3: 63 | close(h->idFd); 64 | error2: 65 | close(h->bdFd); 66 | error1: 67 | free(h); 68 | return NULL; 69 | } 70 | 71 | static void blockdevifSetChangeID(BlockdevifHandle *handle, int sector, uint32_t changeId) { 72 | assert(handle && sector>=0 && sector<(handle->size/BLOCKDEV_BLKSZ)); 73 | handle->idData[sector]=changeId; 74 | } 75 | 76 | static uint32_t blockdevifGetChangeID(BlockdevifHandle *handle, int sector) { 77 | assert(handle && sector>=0 && sector<(handle->size/BLOCKDEV_BLKSZ)); 78 | return handle->idData[sector]; 79 | } 80 | 81 | static int blockdevifGetSectorData(BlockdevifHandle *handle, int sector, uint8_t *buff) { 82 | assert(handle && sector>=0 && sector<(handle->size/BLOCKDEV_BLKSZ)); 83 | memcpy(buff, &handle->bdData[sector*BLOCKDEV_BLKSZ], BLOCKDEV_BLKSZ); 84 | } 85 | 86 | static int blockdevifSetSectorData(BlockdevifHandle *handle, int sector, uint8_t *buff, uint32_t changeId) { 87 | assert(handle && sector>=0 && sector<(handle->size/BLOCKDEV_BLKSZ)); 88 | memcpy(&handle->bdData[sector*BLOCKDEV_BLKSZ], buff, BLOCKDEV_BLKSZ); 89 | blockdevifSetChangeID(handle, sector, changeId); 90 | } 91 | 92 | static void blockdevifForEachBlock(BlockdevifHandle *handle, BlockdevifForEachBlockFn *cb, void *arg) { 93 | for (int i=0; i<(handle->size/BLOCKDEV_BLKSZ); i++) { 94 | cb(i, handle->idData[i], arg); 95 | } 96 | } 97 | 98 | 99 | BlockdevIf blockdevIfBdemu={ 100 | .init=blockdevifInit, 101 | .setChangeID=blockdevifSetChangeID, 102 | .getChangeID=blockdevifGetChangeID, 103 | .getSectorData=blockdevifGetSectorData, 104 | .setSectorData=blockdevifSetSectorData, 105 | .forEachBlock=blockdevifForEachBlock 106 | }; 107 | 108 | 109 | -------------------------------------------------------------------------------- /components/bpp-recv/bd_emu.h: -------------------------------------------------------------------------------- 1 | #ifndef BD_EMU_H 2 | #define BD_EMU_H 3 | 4 | 5 | #include "blockdevif.h" 6 | 7 | extern BlockdevIf blockdevIfBdemu; 8 | 9 | 10 | typedef struct { 11 | const char *file; 12 | } BlockdevIfBdemuDesc; 13 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/bd_flatflash.h: -------------------------------------------------------------------------------- 1 | #ifndef BD_FLATFLASH_H 2 | #define BD_FLATFLASH_H 3 | 4 | #include "blockdevif.h" 5 | 6 | extern BlockdevIf blockdevIfFlatFlash; 7 | 8 | typedef void (*BlockdevIfFlatFlashDoneCb)(uint32_t changeid, void *arg); 9 | 10 | typedef struct { 11 | int major; 12 | int minor; 13 | uint32_t minChangeId; 14 | BlockdevIfFlatFlashDoneCb doneCb; 15 | void *doneCbArg; 16 | } BlockdevIfFlatFlashDesc; 17 | 18 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/bd_ropart.h: -------------------------------------------------------------------------------- 1 | #ifndef BD_ROPART_H 2 | #define BD_ROPART_H 3 | 4 | #include "blockdevif.h" 5 | 6 | extern BlockdevIf blockdevIfRoPart; 7 | 8 | 9 | typedef struct { 10 | int major; 11 | int minor; 12 | } BlockdevIfRoPartDesc; 13 | 14 | void bdropartDumpJournal(BlockdevifHandle *h); 15 | 16 | 17 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/bd_ropart_test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/components/bpp-recv/bd_ropart_test -------------------------------------------------------------------------------- /components/bpp-recv/blkidcache.h: -------------------------------------------------------------------------------- 1 | #ifndef BLKIDCACHE_H 2 | #define BLKIDCACHE_H 3 | 4 | /* 5 | Blockids change pretty often (in theory, every single one changes once per cycle) and writing these 6 | to storage every time can be costly. On the other hand, not writing these to flash has results that 7 | are not nice but not critical either: worst case, after a reboot the system erroneously thinks some 8 | sectors are old and need refreshing. That is why this info can be cached in RAM in some fashion. 9 | */ 10 | 11 | #include 12 | #include "blockdevif.h" 13 | 14 | typedef struct BlkIdCacheHandle BlkIdCacheHandle; 15 | 16 | //Size is in blocks. 17 | BlkIdCacheHandle *idcacheCreate(int size, BlockdevifHandle *blkdev, BlockdevIf *bdif); 18 | 19 | void idcacheSet(BlkIdCacheHandle *h, int block, uint32_t id); 20 | uint32_t idcacheGet(BlkIdCacheHandle *h, int block); 21 | void idcacheFlushToStorage(BlkIdCacheHandle *h); 22 | void idcacheSetSectorData(BlkIdCacheHandle *h, int block, uint8_t *data, uint32_t id); 23 | uint32_t idcacheGetLastChangeId(BlkIdCacheHandle *h); 24 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/blkidcache_noop.c: -------------------------------------------------------------------------------- 1 | /* 2 | Trivial blkidcache that does zero caching at all. Use for testing or on backing that does not 3 | have issues reading/writing data often. 4 | 5 | WARNING: Deprecated. If anything, does not honour bdif->notifyComplete. 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include "blkidcache.h" 11 | 12 | struct BlkIdCacheHandle { 13 | BlockdevifHandle *blkdev; 14 | BlockdevIf *bdif; 15 | }; 16 | 17 | BlkIdCacheHandle *idcacheCreate(int size, BlockdevifHandle *blkdev, BlockdevIf *bdif) { 18 | BlkIdCacheHandle *ret=malloc(sizeof(BlkIdCacheHandle)); 19 | ret->blkdev=blkdev; 20 | ret->bdif=bdif; 21 | return ret; 22 | } 23 | 24 | void idcacheSet(BlkIdCacheHandle *h, int block, uint32_t id) { 25 | h->bdif->setChangeID(h->blkdev, block, id); 26 | } 27 | 28 | uint32_t idcacheGet(BlkIdCacheHandle *h, int block) { 29 | return h->bdif->getChangeID(h->blkdev, block); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /components/bpp-recv/blockdecode.h: -------------------------------------------------------------------------------- 1 | #ifndef BLOCKDECODE_H 2 | #define BLOCKDECODE_H 3 | 4 | #include "blockdevif.h" 5 | 6 | typedef struct BlockDecodeHandle BlockDecodeHandle; 7 | 8 | BlockdevifHandle *blockdecodeGetIf(BlockDecodeHandle *d); 9 | 10 | void blockdecodeStatus(BlockDecodeHandle *d); 11 | 12 | BlockDecodeHandle *blockdecodeInit(int type, int size, BlockdevIf *bdIf, void *bdevdesc); 13 | 14 | void blockdecodeShutDown(BlockDecodeHandle *d); 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /components/bpp-recv/blockdevif.h: -------------------------------------------------------------------------------- 1 | #ifndef BLOCKDEVIF_H 2 | #define BLOCKDEVIF_H 3 | 4 | //Interface to an abstracted block device. Should have the capability of storing both sector change IDs 5 | //as well as sector data. 6 | 7 | #include 8 | #include 9 | 10 | typedef enum { 11 | SSDR_ERROR=0, //some error happened 12 | SSDR_SET, //data is set 13 | SSDR_SETCHID //data + changeId is set 14 | } SetSectorDataRetVal; 15 | 16 | typedef struct BlockdevifHandle BlockdevifHandle; 17 | 18 | typedef void (BlockdevifForEachBlockFn)(int blockno, uint32_t changeId, void *arg); 19 | 20 | typedef struct { 21 | //Initialize the block device. Size is the virtual size of the file, which may be larger 22 | //than the physical size of the storage medium. 23 | BlockdevifHandle* (*init)(void *desc, int size); 24 | //Update a sector to a new changeId. Contents stay the same. 25 | void (*setChangeID)(BlockdevifHandle *handle, int sector, uint32_t changeId); 26 | //Get the changeid for a sector 27 | uint32_t (*getChangeID)(BlockdevifHandle *handle, int sector); 28 | //Set the data for a sector. adv_id is advisory changeid and doesn't need to be taken into account, but 29 | //can be used if setting the changeId is 'free'. 30 | SetSectorDataRetVal (*setSectorData)(BlockdevifHandle *handle, int sector, uint8_t *buff, uint32_t adv_id); 31 | //Get the data for a sector. WARNING: If the block device supports it, the block device returns 32 | //the data that was current when notifyComplete was called, not the last written one. This allows 33 | //the block device to return an integral snapshot, not whatever was halfway throiugh an update. 34 | int (*getSectorData)(BlockdevifHandle *handle, int sector, uint8_t *buff); 35 | //Call the callback for each block to update the sectorID in higher levels 36 | void (*forEachBlock)(BlockdevifHandle *handle, BlockdevifForEachBlockFn *cb, void *arg); 37 | //Is called when the block device has received an entire update. 38 | void (*notifyComplete)(BlockdevifHandle *handle, uint32_t id); 39 | } BlockdevIf; 40 | 41 | 42 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/bma.c: -------------------------------------------------------------------------------- 1 | #include "bma.h" 2 | #include 3 | #include 4 | #include 5 | 6 | struct Bma { 7 | int len; 8 | uint32_t bits[]; 9 | }; 10 | 11 | 12 | Bma *bmaCreate(int len) { 13 | Bma *ret=malloc(sizeof(Bma)+(((len+31)/32))*8); 14 | if (!ret) return NULL; 15 | ret->len=len; 16 | return ret; 17 | } 18 | 19 | void bmaFree(Bma *b) { 20 | free(b); 21 | } 22 | 23 | void bmaSet(Bma *b, int bit, int val) { 24 | if (bit<0 || bit>=b->len) return; 25 | if (val) { 26 | b->bits[bit/32]|=(1<<(bit&31)); 27 | } else { 28 | b->bits[bit/32]&=~(1<<(bit&31)); 29 | } 30 | } 31 | 32 | void bmaSetAll(Bma *b, int val) { 33 | char v=val?0xff:0; 34 | memset(b->bits, v, ((b->len+31)/32)*4); 35 | } 36 | 37 | bool bmaIsSet(Bma *b, int bit) { 38 | if (bit<0 || bit>=b->len) return false; 39 | return (b->bits[bit/32]&(1<<(bit&31)))!=0; 40 | } 41 | 42 | bool bmaIsAll(Bma *b, int val) { 43 | uint32_t v=val?0xFFFFFFFF:0; 44 | for (int i=0; ilen/32; i++) { 45 | if (b->bits[i]!=v) return 0; 46 | } 47 | 48 | int left=b->len&31; 49 | if (left) { 50 | uint32_t mask=0xFFFFFFFF>>(32-left); 51 | int lb=b->bits[b->len/32]&mask; 52 | if (lb!=(v&mask)) return 0; 53 | } 54 | return 1; 55 | } 56 | 57 | bool bmaIsAllSet(Bma *b) { 58 | return bmaIsAll(b, 1); 59 | } 60 | 61 | bool bmaIsAllClear(Bma *b) { 62 | return bmaIsAll(b, 0); 63 | } 64 | 65 | 66 | void bmaDump(Bma *b) { 67 | for (int i=0; ilen; i++) printf("%d", bmaIsSet(b, i)?1:0); 68 | printf("\n"); 69 | } 70 | 71 | //Small testbed. Change 0 into 1 in the next line and compile with 'gcc -o bma bma.c'. 72 | #if 0 73 | #include 74 | 75 | static void testBma(int len) { 76 | Bma *b=bmaCreate(len); 77 | bmaSetAll(b, 1); 78 | assert(bmaIsAllSet(b)); 79 | assert(!bmaIsAllClear(b)); 80 | bmaSet(b, len-1, 0); 81 | assert(!bmaIsAllSet(b)); 82 | assert(!bmaIsAllClear(b)); 83 | bmaSet(b, len-1, 1); 84 | assert(bmaIsAllSet(b)); 85 | assert(!bmaIsAllClear(b)); 86 | bmaSet(b, 0, 0); 87 | assert(!bmaIsAllSet(b)); 88 | assert(!bmaIsAllClear(b)); 89 | 90 | 91 | bmaSetAll(b, 0); 92 | assert(!bmaIsAllSet(b)); 93 | assert(bmaIsAllClear(b)); 94 | bmaSet(b, len-1, 1); 95 | assert(!bmaIsAllSet(b)); 96 | assert(!bmaIsAllClear(b)); 97 | bmaSet(b, len-1, 0); 98 | assert(!bmaIsAllSet(b)); 99 | assert(bmaIsAllClear(b)); 100 | bmaSet(b, 0, 1); 101 | assert(!bmaIsAllSet(b)); 102 | assert(!bmaIsAllClear(b)); 103 | bmaFree(b); 104 | } 105 | 106 | int main() { 107 | testBma(512); 108 | testBma(511); 109 | testBma(513); 110 | testBma(7); 111 | printf("Test OK!\n"); 112 | 113 | } 114 | #endif 115 | 116 | -------------------------------------------------------------------------------- /components/bpp-recv/bma.h: -------------------------------------------------------------------------------- 1 | /* 2 | Small implementation of a BitMapArray, similar to vector in C++. Made because 3 | doing this manually every time is too error-prone... 4 | */ 5 | #ifndef BMA_H 6 | #define BMA_H 7 | 8 | #include 9 | #include 10 | 11 | typedef struct Bma Bma; 12 | 13 | Bma *bmaCreate(int len); 14 | void bmaSet(Bma *b, int bit, int val); 15 | void bmaSetAll(Bma *b, int val); 16 | bool bmaIsSet(Bma *b, int bit); 17 | bool bmaIsAll(Bma *b, int val); 18 | bool bmaIsAllSet(Bma *b); 19 | bool bmaIsAllClear(Bma *b); 20 | void bmaFree(Bma *b); 21 | void bmaDump(Bma *b); 22 | 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /components/bpp-recv/chksign.h: -------------------------------------------------------------------------------- 1 | #ifndef CHKSIGN_H 2 | #define CHKSIGN_H 3 | 4 | #include "recvif.h" 5 | 6 | 7 | void chksignInit(RecvCb *cb); 8 | int chksignRecv(uint8_t *packet, size_t len); 9 | 10 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/chksign_ed25519.c: -------------------------------------------------------------------------------- 1 | /* 2 | Packet signature checking 3 | 4 | Every packet sent out is signed using ECDSA. We check that signature using the micro-ecc library. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "recvif.h" 12 | #include "structs.h" 13 | 14 | #include "ed25519.h" 15 | #include "pubkey.inc" 16 | 17 | static RecvCb *recvCb; 18 | 19 | void chksignInit(RecvCb *cb) { 20 | recvCb=cb; 21 | } 22 | 23 | int chksignRecv(uint8_t *packet, size_t len) { 24 | if (lensig, p->data, plLen, public_key); 30 | if (isOk) { 31 | recvCb(p->data, plLen); 32 | } else { 33 | printf("Signature check failed.\n"); 34 | } 35 | return isOk; 36 | } 37 | -------------------------------------------------------------------------------- /components/bpp-recv/chksign_mbedtls.c: -------------------------------------------------------------------------------- 1 | /* 2 | Packet signature checking 3 | 4 | Every packet sent out is signed using ECDSA/SHA256. We check it using MbedTLS functions. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "recvif.h" 12 | #include "structs.h" 13 | #include "mbedtls/config.h" 14 | #include "mbedtls/entropy.h" 15 | #include "mbedtls/ctr_drbg.h" 16 | #include "mbedtls/ecdsa.h" 17 | 18 | #include "pubkey.inc" 19 | #include "mbedtls/sha256.h" 20 | 21 | static RecvCb *recvCb; 22 | 23 | //We only use the key as a handy store for Q and grp; obviously we do not have the 24 | //private key here. 25 | static mbedtls_ecp_keypair key; 26 | 27 | 28 | //#define ECPARAMS MBEDTLS_ECP_DP_SECP256R1 29 | //#define ECPARAMS MBEDTLS_ECP_DP_CURVE25519 30 | #define ECPARAMS MBEDTLS_ECP_DP_SECP192R1 31 | 32 | void chksignInit(RecvCb *cb) { 33 | int r; 34 | recvCb=cb; 35 | 36 | mbedtls_mpi_init(&key.Q.X); 37 | mbedtls_mpi_init(&key.Q.Y); 38 | mbedtls_mpi_init(&key.Q.Z); 39 | r=mbedtls_ecp_group_load(&key.grp, ECPARAMS); 40 | if (r) printf("group load failed\n"); 41 | r=mbedtls_mpi_read_binary(&key.Q.X, (unsigned char*)&public_key[0], 32); 42 | if (r) printf("read_binary X failed\n"); 43 | // r=mbedtls_mpi_read_binary(&key.Q.Y, (unsigned char*)&public_key[32], 32); 44 | // if (r) printf("read_binary Y failed\n"); 45 | r=mbedtls_mpi_read_binary(&key.Q.Z, (unsigned char*)"\001", 1); 46 | if (r) printf("read_binary Z failed\n"); 47 | } 48 | 49 | void chksignRecv(uint8_t *packet, size_t len) { 50 | if (lendata, plLen, hash, 0); 56 | 57 | mbedtls_mpi mpir, mpis; 58 | mbedtls_mpi_init(&mpir); 59 | mbedtls_mpi_init(&mpis); 60 | mbedtls_mpi_read_binary(&mpir, (unsigned char*)&p->sig[0], 32); 61 | mbedtls_mpi_read_binary(&mpis, (unsigned char*)&p->sig[32], 32); 62 | int isOk=!mbedtls_ecdsa_verify(&key.grp, hash, sizeof(hash), &key.Q, &mpir, &mpis); 63 | 64 | if (isOk) { 65 | recvCb(p->data, plLen); 66 | } else { 67 | printf("Huh? ECDSA signature mismatch!\n"); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /components/bpp-recv/chksign_uecc.c: -------------------------------------------------------------------------------- 1 | /* 2 | Packet signature checking 3 | 4 | Every packet sent out is signed using ECDSA. We check that signature using the micro-ecc library. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "recvif.h" 12 | #include "structs.h" 13 | 14 | #include "uECC.h" 15 | #include "../keys/pubkey.inc" 16 | #include "sha256.h" 17 | 18 | static RecvCb *recvCb; 19 | 20 | void chksignInit(RecvCb *cb) { 21 | recvCb=cb; 22 | } 23 | 24 | void chksignRecv(uint8_t *packet, size_t len) { 25 | if (lendata, plLen); 34 | sha256_final(&sha, hash); 35 | 36 | //Check signature of packet 37 | int isOk=uECC_verify(public_key, hash, sizeof(hash), p->sig, uECC_secp256r1()); 38 | 39 | if (isOk) { 40 | recvCb(p->data, plLen); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /components/bpp-recv/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Component Makefile 3 | # 4 | 5 | 6 | COMPONENT_ADD_INCLUDEDIRS := . common 7 | COMPONENT_SOURCES := . common 8 | COMPONENT_OBJS := bd_flatflash.o blkidcache_mlvl.o blockdecode.o chksign_ed25519.o defec.o hkpackets.o \ 9 | hldemux.o powerdown.o serdec.o subtitle.o crc16-ccitt.o defec_parity.o defec_rs.o \ 10 | bd_ropart.o mountbd.o bma.o 11 | 12 | 13 | -------------------------------------------------------------------------------- /components/bpp-recv/crc16-ccitt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2001-2010 Georges Menie (www.menie.org) 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the University of California, Berkeley nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef _CRC16_H_ 29 | #define _CRC16_H_ 30 | 31 | 32 | #include 33 | unsigned short crc16_ccitt(uint16_t oldcrc, const void *buf, int len); 34 | 35 | #endif /* _CRC16_H_ */ 36 | -------------------------------------------------------------------------------- /components/bpp-recv/defec.c: -------------------------------------------------------------------------------- 1 | /* 2 | Try to ressurect missing packets using FEC 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "recvif.h" 11 | #include "structs.h" 12 | #include "defec.h" 13 | #include "esp_attr.h" 14 | 15 | 16 | extern const FecDecoder fecDecoderParity; 17 | extern const FecDecoder fecDecoderRs; 18 | 19 | static const FecDecoder *decoders[]={ 20 | &fecDecoderParity, 21 | &fecDecoderRs, 22 | NULL 23 | }; 24 | 25 | typedef struct { 26 | int k, n, algId; 27 | } FecSavedStatus; 28 | 29 | static RTC_DATA_ATTR FecSavedStatus savedStatus; 30 | 31 | static RecvCb *recvCb; 32 | static const FecDecoder *currDecoder; 33 | static int currK, currN; 34 | static size_t maxPacketSize; 35 | static portMUX_TYPE statusMux = portMUX_INITIALIZER_UNLOCKED; 36 | static FecStatus status; 37 | static int lastRecvSerial; 38 | 39 | void defecInit(RecvCb *cb, int maxLen) { 40 | currDecoder=decoders[0]; 41 | currK=3; 42 | currN=4; 43 | maxPacketSize=maxLen; 44 | recvCb=cb; 45 | if (savedStatus.k!=0 && savedStatus.n!=0) { 46 | //restore status 47 | int i; 48 | currK=savedStatus.k; 49 | currN=savedStatus.n; 50 | for (i=0; decoders[i]!=NULL; i++) { 51 | if (decoders[i]->algId==savedStatus.algId) break; 52 | } 53 | currDecoder=decoders[i]; 54 | } 55 | currDecoder->init(currK, currN, maxLen); 56 | } 57 | 58 | void defecGetStatus(FecStatus *st) { 59 | portENTER_CRITICAL(&statusMux); 60 | memcpy(st, &status, sizeof(status)); 61 | portEXIT_CRITICAL(&statusMux); 62 | } 63 | 64 | static void defecRecvDefecced(uint8_t *packet, size_t len) { 65 | recvCb(packet, len); 66 | } 67 | 68 | 69 | void defecRecv(uint8_t *packet, size_t len) { 70 | if (lenserial); 75 | if (serial==0) { 76 | //Special packet: contains fec parameters 77 | if (plLendata; 79 | if (currDecoder==NULL || \ 80 | currDecoder->algId!=d->fecAlgoId || \ 81 | currK!=ntohs(d->k) || \ 82 | currN!=ntohs(d->n)) { 83 | //Fec parameters changed. Close current decoder, open new one. 84 | if (currDecoder) currDecoder->deinit(); 85 | 86 | currK=ntohs(d->k); 87 | currN=ntohs(d->n); 88 | savedStatus.k=currK; 89 | savedStatus.n=currN; 90 | savedStatus.algId=d->fecAlgoId; 91 | int i; 92 | for (i=0; decoders[i]!=NULL; i++) { 93 | if (decoders[i]->algId==d->fecAlgoId) break; 94 | } 95 | currDecoder=decoders[i]; 96 | if (!currDecoder) { 97 | printf("FEC: No decoder found for algo id %d!\n", d->fecAlgoId); 98 | } else { 99 | int r=currDecoder->init(currK, currN, maxPacketSize); 100 | if (!r) { 101 | currDecoder=NULL; 102 | printf("FEC: Couldn't initialize decoder id %d for k=%d n=%d!\n", d->fecAlgoId, currK, currN); 103 | } else { 104 | printf("FEC: Changed to decoder id %d, k=%d n=%d!\n", d->fecAlgoId, currK, currN); 105 | } 106 | } 107 | } 108 | return; 109 | } 110 | if (!currDecoder) return; //can't decode! 111 | 112 | if (serial<=lastRecvSerial) return; //dup 113 | 114 | if (lastRecvSerial!=0) { 115 | portENTER_CRITICAL(&statusMux); 116 | status.packetsInTotal+=serial-lastRecvSerial; 117 | status.packetsInMissed+=(serial-lastRecvSerial)-1; 118 | portEXIT_CRITICAL(&statusMux); 119 | } 120 | lastRecvSerial=serial; 121 | 122 | currDecoder->recv(p->data, plLen, serial, defecRecvDefecced); 123 | } 124 | -------------------------------------------------------------------------------- /components/bpp-recv/defec.h: -------------------------------------------------------------------------------- 1 | #ifndef DEFEC_H 2 | #define DEFEC_H 3 | 4 | #include "recvif.h" 5 | 6 | typedef void (*FecSendDefeccedPacket)(uint8_t *packet, size_t len); 7 | typedef int (*FecDecoderInit)(int k, int n, int maxsize); 8 | typedef void (*FecDecoderRecv)(uint8_t *packet, size_t len, int serial, FecSendDefeccedPacket sendFn); 9 | typedef void (*FecDecoderDeinit)(); 10 | 11 | typedef struct { 12 | const int algId; 13 | FecDecoderInit init; 14 | FecDecoderRecv recv; 15 | FecDecoderDeinit deinit; 16 | } FecDecoder; 17 | 18 | 19 | 20 | typedef struct { 21 | int packetsInTotal; 22 | int packetsInMissed; 23 | } FecStatus; 24 | 25 | 26 | void defecInit(RecvCb *cb, int maxLen); 27 | void defecRecv(uint8_t *packet, size_t len); 28 | void defecGetStatus(FecStatus *st); 29 | 30 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/defec_rs.c: -------------------------------------------------------------------------------- 1 | /* 2 | Try to ressurect missing packets using the parity packet 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "recvif.h" 10 | #include "structs.h" 11 | #include "defec.h" 12 | #include "redundancy.h" 13 | 14 | static uint8_t *rsPacket; 15 | static gbf_int_t *rsSerial; 16 | static int curBin; // = serial/rsN 17 | static int recved; 18 | static int rsK, rsN; 19 | static int curLen; 20 | static int lastOkBin; 21 | 22 | 23 | static int defecRsInit(int k, int n, int maxLen) { 24 | rsPacket=malloc(maxLen*k); 25 | rsSerial=malloc(sizeof(gbf_int_t)*k); 26 | if (rsPacket==NULL || rsSerial==NULL) { 27 | free(rsPacket); 28 | free(rsSerial); 29 | return 0; 30 | } 31 | rsK=k; 32 | rsN=n; 33 | recved=0; 34 | curLen=0; 35 | lastOkBin=0; 36 | gbf_init(GBF_POLYNOME); 37 | return 1; 38 | } 39 | 40 | static void defecRsDeinit() { 41 | free(rsPacket); 42 | free(rsSerial); 43 | rsPacket=NULL; 44 | rsSerial=NULL; 45 | } 46 | 47 | static int flushRsState(FecSendDefeccedPacket sendFn) { 48 | int r=0; 49 | if (recved>=rsK) { 50 | uint8_t *out=malloc(rsK*curLen); 51 | if (out!=NULL) { 52 | gbf_decode((gbf_int_t*)out, (gbf_int_t*)rsPacket, rsSerial, rsK, (curLen/sizeof(gbf_int_t))); 53 | for (int i=0; i 2 | #include 3 | 4 | #ifndef HEXDUMP_COLS 5 | #define HEXDUMP_COLS 8 6 | #endif 7 | 8 | void hexdump(void *mem, unsigned int len) 9 | { 10 | unsigned int i, j; 11 | 12 | for(i = 0; i < len + ((len % HEXDUMP_COLS) ? (HEXDUMP_COLS - len % HEXDUMP_COLS) : 0); i++) 13 | { 14 | /* print offset */ 15 | if(i % HEXDUMP_COLS == 0) 16 | { 17 | printf("0x%06x: ", i); 18 | } 19 | /* print hex data */ 20 | if(i < len) 21 | { 22 | printf("%02x ", 0xFF & ((char*)mem)[i]); 23 | } 24 | else /* end of block, just aligning for ASCII dump */ 25 | { 26 | printf(" "); 27 | } 28 | 29 | /* print ASCII dump */ 30 | if(i % HEXDUMP_COLS == (HEXDUMP_COLS - 1)) 31 | { 32 | for(j = i - (HEXDUMP_COLS - 1); j <= i; j++) 33 | { 34 | if(j >= len) /* end of block, not really printing */ 35 | { 36 | putchar(' '); 37 | } 38 | else if(isprint(((char*)mem)[j])) /* printable char */ 39 | { 40 | putchar(0xFF & ((char*)mem)[j]); 41 | } 42 | else /* other char */ 43 | { 44 | putchar('.'); 45 | } 46 | } 47 | putchar('\n'); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /components/bpp-recv/hexdump.h: -------------------------------------------------------------------------------- 1 | #ifndef HEXDUMP_H 2 | #define HEXDUMP_H 3 | 4 | void hexdump(void *mem, unsigned int len); 5 | 6 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/hkpackets.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "hldemux.h" 4 | #include "structs.h" 5 | #include "powerdown.h" 6 | #include "hkpackets.h" 7 | 8 | static void hkpacketsRecv(int subtype, uint8_t *data, int len, void *arg) { 9 | if (subtype==HKPACKET_SUBTYPE_NEXTCATALOG) { 10 | HKPacketNextCatalog *p=(HKPacketNextCatalog*)data; 11 | int delayMs=ntohl(p->delayMs); 12 | printf("HKPacket: next catalog in %d ms\n", delayMs); 13 | //Use address of init function as random reference. 14 | powerCanSleepFor((int)hkpacketsInit, delayMs); 15 | } else { 16 | printf("hkpackets: Unknown housekeeping packet subtype: %d\n", subtype); 17 | } 18 | } 19 | 20 | void hkpacketsInit() { 21 | hldemuxAddType(HLPACKET_TYPE_HK, hkpacketsRecv, NULL); 22 | powerHold((int)hkpacketsInit, 30*1000); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /components/bpp-recv/hkpackets.h: -------------------------------------------------------------------------------- 1 | #ifndef HKPACKETS_H 2 | #define HKPACKETS_H 3 | 4 | void hkpacketsInit(); 5 | 6 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/hldemux.c: -------------------------------------------------------------------------------- 1 | /* 2 | Distribute packets depending on type. 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "recvif.h" 10 | #include "structs.h" 11 | 12 | #include "hldemux.h" 13 | 14 | typedef struct HlCallbackInfo HlCallbackInfo; 15 | 16 | struct HlCallbackInfo { 17 | int type; 18 | HlCallback *cb; 19 | void *arg; 20 | HlCallbackInfo *next; 21 | }; 22 | 23 | static HlCallbackInfo *cbinfo=NULL; 24 | 25 | 26 | void hldemuxAddType(int type, HlCallback cb, void *arg) { 27 | HlCallbackInfo *item=malloc(sizeof(HlCallbackInfo)); 28 | item->type=type; 29 | item->cb=cb; 30 | item->arg=arg; 31 | item->next=cbinfo; 32 | cbinfo=item; 33 | } 34 | 35 | void hldemuxRecv(uint8_t *packet, size_t len) { 36 | if (lentype); 41 | int subtype=ntohs(p->subtype); 42 | 43 | int found=0; 44 | for (HlCallbackInfo *i=cbinfo; i!=NULL; i=i->next) { 45 | if (i->type==type) { 46 | i->cb(subtype, p->data, plLen, i->arg); 47 | found=1; 48 | } 49 | } 50 | if (!found) { 51 | printf("hldemux: Huh? No handler known for type %d (subtype %d)\n", type, subtype); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /components/bpp-recv/hldemux.h: -------------------------------------------------------------------------------- 1 | #ifndef HLDEMUX_H 2 | #define HLDEMUX_H 3 | 4 | #include 5 | #include "recvif.h" 6 | 7 | typedef void (HlCallback)(int subtype, uint8_t *data, int len, void *arg); 8 | 9 | void hldemuxAddType(int type, HlCallback cb, void *arg); 10 | void hldemuxRecv(uint8_t *packet, size_t len); 11 | 12 | 13 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/mountbd.h: -------------------------------------------------------------------------------- 1 | #ifndef MOUNTBD_H 2 | #define MOUNTBD_H 3 | 4 | int bd_mount(BlockdevIf *iface, BlockdevifHandle *h, const char *path, size_t max_files); 5 | 6 | 7 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/partemu/esp_attr.h: -------------------------------------------------------------------------------- 1 | 2 | //Dummy 3 | 4 | #define RTC_DATA_ATTR -------------------------------------------------------------------------------- /components/bpp-recv/partemu/esp_err.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #pragma once 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | typedef int32_t esp_err_t; 25 | 26 | /* Definitions for error constants. */ 27 | 28 | #define ESP_OK 0 29 | #define ESP_FAIL -1 30 | 31 | #define ESP_ERR_NO_MEM 0x101 32 | #define ESP_ERR_INVALID_ARG 0x102 33 | #define ESP_ERR_INVALID_STATE 0x103 34 | #define ESP_ERR_INVALID_SIZE 0x104 35 | #define ESP_ERR_NOT_FOUND 0x105 36 | #define ESP_ERR_NOT_SUPPORTED 0x106 37 | #define ESP_ERR_TIMEOUT 0x107 38 | #define ESP_ERR_INVALID_RESPONSE 0x108 39 | #define ESP_ERR_INVALID_CRC 0x109 40 | 41 | #define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */ 42 | 43 | void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) __attribute__((noreturn)); 44 | 45 | #ifndef __ASSERT_FUNC 46 | /* This won't happen on IDF, which defines __ASSERT_FUNC in assert.h, but it does happen when building on the host which 47 | uses /usr/include/assert.h or equivalent. 48 | */ 49 | #ifdef __ASSERT_FUNCTION 50 | #define __ASSERT_FUNC __ASSERT_FUNCTION /* used in glibc assert.h */ 51 | #else 52 | #define __ASSERT_FUNC "??" 53 | #endif 54 | #endif 55 | 56 | /** 57 | * Macro which can be used to check the error code, 58 | * and terminate the program in case the code is not ESP_OK. 59 | * Prints the error code, error location, and the failed statement to serial output. 60 | * 61 | * Disabled if assertions are disabled. 62 | */ 63 | #ifdef NDEBUG 64 | #define ESP_ERROR_CHECK(x) do { \ 65 | esp_err_t rc = (x); \ 66 | (void) sizeof(rc); \ 67 | } while(0); 68 | #else 69 | #define ESP_ERROR_CHECK(x) do { \ 70 | esp_err_t rc = (x); \ 71 | if (rc != ESP_OK) { \ 72 | _esp_error_check_failed(rc, __FILE__, __LINE__, \ 73 | __ASSERT_FUNC, #x); \ 74 | } \ 75 | } while(0); 76 | #endif 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | -------------------------------------------------------------------------------- /components/bpp-recv/partemu/esp_system.h: -------------------------------------------------------------------------------- 1 | #include 2 | //Dummy 3 | 4 | 5 | //Warning: pretty crude 6 | static inline int system_get_time() { 7 | return time(NULL)*1000; 8 | } 9 | -------------------------------------------------------------------------------- /components/bpp-recv/partemu/freertos/FreeRTOS.h: -------------------------------------------------------------------------------- 1 | 2 | //dummy -------------------------------------------------------------------------------- /components/bpp-recv/partemu/freertos/portmacro.h: -------------------------------------------------------------------------------- 1 | 2 | typedef int portMUX_TYPE; 3 | #define portMUX_INITIALIZER_UNLOCKED 0 4 | 5 | #define portENTER_CRITICAL(x) 6 | #define portEXIT_CRITICAL(x) 7 | -------------------------------------------------------------------------------- /components/bpp-recv/partemu/freertos/queue.h: -------------------------------------------------------------------------------- 1 | 2 | //dummy 3 | 4 | 5 | #define portMAX_DELAY 1 6 | #define portTICK_PERIOD_MS 1 -------------------------------------------------------------------------------- /components/bpp-recv/partemu/freertos/semphr.h: -------------------------------------------------------------------------------- 1 | 2 | //dummy 3 | 4 | typedef int SemaphoreHandle_t; 5 | #define xSemaphoreTake( xSemaphore, xBlockTime ) void 6 | #define xSemaphoreGive( xSemaphore ) void 7 | #define xSemaphoreCreateMutex() 1 8 | -------------------------------------------------------------------------------- /components/bpp-recv/partemu/freertos/timers.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | //dummy 4 | 5 | 6 | typedef int TimerHandle_t; 7 | 8 | #define xTimerReset( xTimer, xTicksToWait ) void 9 | #define xTimerStart( xTimer, xTicksToWait ) void 10 | 11 | #define xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction ) 1 12 | 13 | -------------------------------------------------------------------------------- /components/bpp-recv/partemu/partemu.c: -------------------------------------------------------------------------------- 1 | /* 2 | Quick and dirty file-backed implementation of the esp32 partition api with files as backing to 3 | compile and test the flash blockdevice backends on a host cpu. 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "esp_partition.h" 13 | #include 14 | 15 | const esp_partition_t *esp_partition_find_first(esp_partition_type_t type, esp_partition_subtype_t subtype, const char *label) { 16 | char buf[128]; 17 | esp_partition_t *part=malloc(sizeof(esp_partition_t)); 18 | sprintf(buf, "part-%d-%d.img", (int)type, (int)subtype); 19 | int f=open(buf, O_RDWR|O_CREAT, 0644); 20 | if (f<=0) { 21 | perror(buf); 22 | exit(1); 23 | } 24 | part->address=f; 25 | part->type=type; 26 | part->subtype=subtype; 27 | part->size=lseek(part->address, 0, SEEK_END); 28 | return part; 29 | } 30 | 31 | esp_err_t esp_partition_read(const esp_partition_t *part, size_t src_offset, void *dst, size_t size) { 32 | lseek((int)part->address, src_offset, SEEK_SET); 33 | read((int)part->address, dst, size); 34 | return ESP_OK; 35 | } 36 | 37 | esp_err_t esp_partition_write(const esp_partition_t *part, size_t dst_offset, const void *src, size_t size) { 38 | uint8_t *buf=malloc(size); 39 | uint8_t *bsrc=(uint8_t*)src; 40 | lseek((int)part->address, dst_offset, SEEK_SET); 41 | //Flash bits can only be cleared when writing. Simulate that here. 42 | read((int)part->address, buf, size); 43 | for (int i=0; iaddress, dst_offset, SEEK_SET); 45 | write((int)part->address, buf, size); 46 | return ESP_OK; 47 | } 48 | 49 | esp_err_t esp_partition_erase_range(const esp_partition_t *part, uint32_t start_addr, uint32_t size) { 50 | //must be on page border 51 | assert((start_addr&4095)==0); 52 | assert((size&4095)==0); 53 | //write all f's 54 | uint8_t *buf=malloc(size); 55 | for (int i=0; iaddress, start_addr, SEEK_SET); 57 | write((int)part->address, buf, size); 58 | return ESP_OK; 59 | } 60 | 61 | esp_err_t esp_partition_mmap(const esp_partition_t* partition, uint32_t offset, uint32_t size, 62 | spi_flash_mmap_memory_t memory, 63 | const void** out_ptr, spi_flash_mmap_handle_t* out_handle) { 64 | 65 | *out_ptr=mmap(NULL, size, PROT_READ, MAP_SHARED, partition->address, offset); 66 | assert (*out_ptr!=MAP_FAILED); 67 | return ESP_OK; 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /components/bpp-recv/powerdown.h: -------------------------------------------------------------------------------- 1 | #ifndef POWERDOWN_H 2 | #define POWERDOWN_H 3 | 4 | #define POWERDOWN_DBG 1 5 | 6 | typedef enum { 7 | POWER_MODE_BPP=0, 8 | POWER_MODE_UPY, 9 | } PowerMode; 10 | 11 | #define NO_POWER_MODES 2 12 | 13 | 14 | /* 15 | This callback is called when: 16 | - All processes active have released their power hold. delayMs is the time the ESP can sleep, and 17 | newMode is the mode it should wake up in. 18 | - A higher-priority mode deep sleep timer passed. We need to reboot into that mode immediately. In 19 | this case, newMode is different from the current mode and delayMs = 0. 20 | */ 21 | typedef void (PowerDownCb)(int delayMs, void *arg, PowerMode newmode); 22 | 23 | /* 24 | Initialize the power down managed. Cb is a callback for when the ESP32 needs to power down or reboot, 25 | mode is the power mode we're currently in, dbg is 1 if it's okay to spit debug info to the console. 26 | Arg is passed straight to the callback. 27 | */ 28 | void powerDownMgrInit(PowerDownCb *cb, void *arg, PowerMode mode, bool dbg); 29 | 30 | 31 | /* 32 | Each process that can keep the esp32 from sleeping has a reference, which is a 32-bit integer called 'ref'. This 33 | ref can be randomly chosen, for example it can be the address of an object the process is bound to. As long as the 34 | ref is the same over calls, the powerdown manager knows the calls are done by the same process. 35 | - powerHold(ref, holdTimeMs) - Stop the ESP32 from going to sleep for at least holdTimeMs milliseconds. 36 | - powerCanSleepFor(ref, delayMs) - ESP32 is allowed to go to sleep, but should wake up in at least delayMs milliseconds. 37 | - powerCanSleep(ref) - ESP32 is allowed to go to sleep, period. 38 | */ 39 | 40 | #if POWERDOWN_DBG 41 | #define powerHold(ref, ht) _powerHold(ref, ht, __FUNCTION__, __LINE__) 42 | #define powerCanSleepFor(ref, del) _powerCanSleepFor(ref, del, __FUNCTION__, __LINE__) 43 | #define powerCanSleep(ref) _powerCanSleep(ref, __FUNCTION__, __LINE__) 44 | #else 45 | #define powerHold(ref) _powerHold(ref, "", 0) 46 | #define powerCanSleepFor(ref, del) _powerCanSleepFor(ref, del, "", 0) 47 | #define powerCanSleep(ref) _powerCanSleep(ref, "", 0) 48 | #endif 49 | void _powerHold(int ref, int holdTimeMs, const char *fn, const int line); 50 | void _powerCanSleepFor(int ref, int delayMs, const char *fn, const int line); 51 | void _powerCanSleep(int ref, const char *fn, const int line); 52 | 53 | 54 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/pubkey.inc: -------------------------------------------------------------------------------- 1 | //Generated on 2017-07-20 10:03:49 2 | static uint8_t public_key[32]={ 3 | 0xFE, 0xB2, 0x64, 0xFD, 0xF0, 0x31, 0xD9, 0x74, 0xF0, 0x47, 0x4A, 0x06, 0x72, 0x6A, 0x2E, 0x2D, 4 | 0xD9, 0x2E, 0x1A, 0x07, 0xEC, 0x46, 0xF8, 0x44, 0xEC, 0x13, 0x04, 0xE5, 0x30, 0x0E, 0xB5, 0x3D}; 5 | -------------------------------------------------------------------------------- /components/bpp-recv/recvif.h: -------------------------------------------------------------------------------- 1 | #ifndef SENDIF_H 2 | #define SENDIF_H 3 | 4 | typedef void (RecvCb)(uint8_t *packet, size_t len); 5 | 6 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/serdec.c: -------------------------------------------------------------------------------- 1 | /* 2 | Decode the flexible length packets encoded in the fixed-length stream 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "recvif.h" 10 | #include "structs.h" 11 | #ifndef HOST_BUILD 12 | #include "rom/crc.h" 13 | #endif 14 | #include "crc16-ccitt.h" 15 | #include "hexdump.h" 16 | 17 | #define MAX_PACKET_LEN (8*1024) 18 | 19 | static RecvCb *recvCb; 20 | 21 | static uint8_t serPacket[MAX_PACKET_LEN]; 22 | static SerdesHdr hdr; 23 | static int pos=-1; 24 | static int hdrBytesScanned=0; //for information purposes 25 | 26 | 27 | void serdecInit(RecvCb *cb) { 28 | recvCb=cb; 29 | } 30 | 31 | static int scanHdr(uint8_t in) { 32 | uint8_t *h=(uint8_t*)&hdr; 33 | //Scanning for header 34 | hdrBytesScanned++; 35 | for (int x=1; x(len-i)) left=len-i; 93 | memcpy(&serPacket[pos], &packet[i], left); 94 | //printf("Pos=%d plen=%d len=%d i=%d (len-i)=%d left=%d\n", pos, plen, len, i, len-i, left); 95 | pos+=left; 96 | i+=left; 97 | if (pos==plen) { 98 | finishPacket(); 99 | pos=-1; 100 | memset(&hdr, 0, sizeof(SerdesHdr)); 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /components/bpp-recv/serdec.h: -------------------------------------------------------------------------------- 1 | #ifndef SERDEC_H 2 | #define SERDEC_H 3 | 4 | #include "recvif.h" 5 | 6 | void serdecInit(RecvCb *cb); 7 | void serdecRecv(uint8_t *packet, size_t len); 8 | 9 | #endif -------------------------------------------------------------------------------- /components/bpp-recv/subtitle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "hldemux.h" 3 | 4 | static void subtitleRecv(int subtype, uint8_t *data, int len, void *arg) { 5 | data[len]=0; 6 | printf("Subtitle stream %d: %s\n", subtype, data); 7 | } 8 | 9 | void subtitleInit() { 10 | // hldemuxAddType(HLPACKET_TYPE_SUBTITLES, subtitleRecv, NULL); 11 | hldemuxAddType(2, subtitleRecv, NULL); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /components/bpp-recv/subtitle.h: -------------------------------------------------------------------------------- 1 | #ifndef SUBTITLE_H 2 | #define SUBTITLE_H 3 | 4 | void subtitleInit(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /components/ed25519/add_scalar.c: -------------------------------------------------------------------------------- 1 | #include "ed25519.h" 2 | #include "ge.h" 3 | #include "sc.h" 4 | #include "sha512.h" 5 | 6 | 7 | /* see http://crypto.stackexchange.com/a/6215/4697 */ 8 | void ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar) { 9 | const unsigned char SC_1[32] = {1}; /* scalar with value 1 */ 10 | 11 | unsigned char n[32]; 12 | ge_p3 nB; 13 | ge_p1p1 A_p1p1; 14 | ge_p3 A; 15 | ge_p3 public_key_unpacked; 16 | ge_cached T; 17 | 18 | sha512_context hash; 19 | unsigned char hashbuf[64]; 20 | 21 | int i; 22 | 23 | /* copy the scalar and clear highest bit */ 24 | for (i = 0; i < 31; ++i) { 25 | n[i] = scalar[i]; 26 | } 27 | n[31] = scalar[31] & 127; 28 | 29 | /* private key: a = n + t */ 30 | if (private_key) { 31 | sc_muladd(private_key, SC_1, n, private_key); 32 | 33 | // https://github.com/orlp/ed25519/issues/3 34 | sha512_init(&hash); 35 | sha512_update(&hash, private_key + 32, 32); 36 | sha512_update(&hash, scalar, 32); 37 | sha512_final(&hash, hashbuf); 38 | for (i = 0; i < 32; ++i) { 39 | private_key[32 + i] = hashbuf[i]; 40 | } 41 | } 42 | 43 | /* public key: A = nB + T */ 44 | if (public_key) { 45 | /* if we know the private key we don't need a point addition, which is faster */ 46 | /* using a "timing attack" you could find out wether or not we know the private 47 | key, but this information seems rather useless - if this is important pass 48 | public_key and private_key seperately in 2 function calls */ 49 | if (private_key) { 50 | ge_scalarmult_base(&A, private_key); 51 | } else { 52 | /* unpack public key into T */ 53 | ge_frombytes_negate_vartime(&public_key_unpacked, public_key); 54 | fe_neg(public_key_unpacked.X, public_key_unpacked.X); /* undo negate */ 55 | fe_neg(public_key_unpacked.T, public_key_unpacked.T); /* undo negate */ 56 | ge_p3_to_cached(&T, &public_key_unpacked); 57 | 58 | /* calculate n*B */ 59 | ge_scalarmult_base(&nB, n); 60 | 61 | /* A = n*B + T */ 62 | ge_add(&A_p1p1, &nB, &T); 63 | ge_p1p1_to_p3(&A, &A_p1p1); 64 | } 65 | 66 | /* pack public key */ 67 | ge_p3_tobytes(public_key, &A); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /components/ed25519/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Component Makefile 3 | # 4 | 5 | 6 | COMPONENT_ADD_INCLUDEDIRS := include 7 | COMPONENT_SRCDIRS := . 8 | COMPONENT_PRIV_INCLUDEDIRS := . 9 | 10 | CFLAGS := $(filter-out -O1 -O2 -Og,$(CFLAGS)) -O3 -------------------------------------------------------------------------------- /components/ed25519/ed25519.h: -------------------------------------------------------------------------------- 1 | #ifndef ED25519_H 2 | #define ED25519_H 3 | 4 | #include 5 | 6 | #if defined(_WIN32) 7 | #if defined(ED25519_BUILD_DLL) 8 | #define ED25519_DECLSPEC __declspec(dllexport) 9 | #elif defined(ED25519_DLL) 10 | #define ED25519_DECLSPEC __declspec(dllimport) 11 | #else 12 | #define ED25519_DECLSPEC 13 | #endif 14 | #else 15 | #define ED25519_DECLSPEC 16 | #endif 17 | 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #ifndef ED25519_NO_SEED 24 | int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed); 25 | #endif 26 | 27 | void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed); 28 | void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key); 29 | int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key); 30 | void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar); 31 | void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key); 32 | 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /components/ed25519/fe.h: -------------------------------------------------------------------------------- 1 | #ifndef FE_H 2 | #define FE_H 3 | 4 | #include "fixedint.h" 5 | 6 | 7 | /* 8 | fe means field element. 9 | Here the field is \Z/(2^255-19). 10 | An element t, entries t[0]...t[9], represents the integer 11 | t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. 12 | Bounds on each t[i] vary depending on context. 13 | */ 14 | 15 | 16 | typedef int32_t fe[10]; 17 | 18 | 19 | void fe_0(fe h); 20 | void fe_1(fe h); 21 | 22 | void fe_frombytes(fe h, const unsigned char *s); 23 | void fe_tobytes(unsigned char *s, const fe h); 24 | 25 | void fe_copy(fe h, const fe f); 26 | int fe_isnegative(const fe f); 27 | int fe_isnonzero(const fe f); 28 | void fe_cmov(fe f, const fe g, unsigned int b); 29 | void fe_cswap(fe f, fe g, unsigned int b); 30 | 31 | void fe_neg(fe h, const fe f); 32 | void fe_add(fe h, const fe f, const fe g); 33 | void fe_invert(fe out, const fe z); 34 | void fe_sq(fe h, const fe f); 35 | void fe_sq2(fe h, const fe f); 36 | void fe_mul(fe h, const fe f, const fe g); 37 | void fe_mul121666(fe h, fe f); 38 | void fe_pow22523(fe out, const fe z); 39 | void fe_sub(fe h, const fe f, const fe g); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /components/ed25519/fixedint.h: -------------------------------------------------------------------------------- 1 | /* 2 | Portable header to provide the 32 and 64 bits type. 3 | 4 | Not a compatible replacement for , do not blindly use it as such. 5 | */ 6 | 7 | #if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED) 8 | #include 9 | #define FIXEDINT_H_INCLUDED 10 | 11 | #if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C) 12 | #include 13 | #define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) 14 | #endif 15 | #endif 16 | 17 | 18 | #ifndef FIXEDINT_H_INCLUDED 19 | #define FIXEDINT_H_INCLUDED 20 | 21 | #include 22 | 23 | /* (u)int32_t */ 24 | #ifndef uint32_t 25 | #if (ULONG_MAX == 0xffffffffUL) 26 | typedef unsigned long uint32_t; 27 | #elif (UINT_MAX == 0xffffffffUL) 28 | typedef unsigned int uint32_t; 29 | #elif (USHRT_MAX == 0xffffffffUL) 30 | typedef unsigned short uint32_t; 31 | #endif 32 | #endif 33 | 34 | 35 | #ifndef int32_t 36 | #if (LONG_MAX == 0x7fffffffL) 37 | typedef signed long int32_t; 38 | #elif (INT_MAX == 0x7fffffffL) 39 | typedef signed int int32_t; 40 | #elif (SHRT_MAX == 0x7fffffffL) 41 | typedef signed short int32_t; 42 | #endif 43 | #endif 44 | 45 | 46 | /* (u)int64_t */ 47 | #if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L) 48 | typedef long long int64_t; 49 | typedef unsigned long long uint64_t; 50 | 51 | #define UINT64_C(v) v ##ULL 52 | #define INT64_C(v) v ##LL 53 | #elif defined(__GNUC__) 54 | __extension__ typedef long long int64_t; 55 | __extension__ typedef unsigned long long uint64_t; 56 | 57 | #define UINT64_C(v) v ##ULL 58 | #define INT64_C(v) v ##LL 59 | #elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC) 60 | typedef long long int64_t; 61 | typedef unsigned long long uint64_t; 62 | 63 | #define UINT64_C(v) v ##ULL 64 | #define INT64_C(v) v ##LL 65 | #elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC) 66 | typedef __int64 int64_t; 67 | typedef unsigned __int64 uint64_t; 68 | 69 | #define UINT64_C(v) v ##UI64 70 | #define INT64_C(v) v ##I64 71 | #endif 72 | #endif 73 | -------------------------------------------------------------------------------- /components/ed25519/ge.h: -------------------------------------------------------------------------------- 1 | #ifndef GE_H 2 | #define GE_H 3 | 4 | #include "fe.h" 5 | 6 | 7 | /* 8 | ge means group element. 9 | 10 | Here the group is the set of pairs (x,y) of field elements (see fe.h) 11 | satisfying -x^2 + y^2 = 1 + d x^2y^2 12 | where d = -121665/121666. 13 | 14 | Representations: 15 | ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z 16 | ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT 17 | ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T 18 | ge_precomp (Duif): (y+x,y-x,2dxy) 19 | */ 20 | 21 | typedef struct { 22 | fe X; 23 | fe Y; 24 | fe Z; 25 | } ge_p2; 26 | 27 | typedef struct { 28 | fe X; 29 | fe Y; 30 | fe Z; 31 | fe T; 32 | } ge_p3; 33 | 34 | typedef struct { 35 | fe X; 36 | fe Y; 37 | fe Z; 38 | fe T; 39 | } ge_p1p1; 40 | 41 | typedef struct { 42 | fe yplusx; 43 | fe yminusx; 44 | fe xy2d; 45 | } ge_precomp; 46 | 47 | typedef struct { 48 | fe YplusX; 49 | fe YminusX; 50 | fe Z; 51 | fe T2d; 52 | } ge_cached; 53 | 54 | void ge_p3_tobytes(unsigned char *s, const ge_p3 *h); 55 | void ge_tobytes(unsigned char *s, const ge_p2 *h); 56 | int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s); 57 | 58 | void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); 59 | void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); 60 | void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b); 61 | void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q); 62 | void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q); 63 | void ge_scalarmult_base(ge_p3 *h, const unsigned char *a); 64 | 65 | void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p); 66 | void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p); 67 | void ge_p2_0(ge_p2 *h); 68 | void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p); 69 | void ge_p3_0(ge_p3 *h); 70 | void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p); 71 | void ge_p3_to_cached(ge_cached *r, const ge_p3 *p); 72 | void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /components/ed25519/include/ed25519.h: -------------------------------------------------------------------------------- 1 | #ifndef ED25519_H 2 | #define ED25519_H 3 | 4 | #include 5 | 6 | #if defined(_WIN32) 7 | #if defined(ED25519_BUILD_DLL) 8 | #define ED25519_DECLSPEC __declspec(dllexport) 9 | #elif defined(ED25519_DLL) 10 | #define ED25519_DECLSPEC __declspec(dllimport) 11 | #else 12 | #define ED25519_DECLSPEC 13 | #endif 14 | #else 15 | #define ED25519_DECLSPEC 16 | #endif 17 | 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #ifndef ED25519_NO_SEED 24 | int ED25519_DECLSPEC ed25519_create_seed(unsigned char *seed); 25 | #endif 26 | 27 | void ED25519_DECLSPEC ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed); 28 | void ED25519_DECLSPEC ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key); 29 | int ED25519_DECLSPEC ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key); 30 | void ED25519_DECLSPEC ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar); 31 | void ED25519_DECLSPEC ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key); 32 | 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /components/ed25519/key_exchange.c: -------------------------------------------------------------------------------- 1 | #include "ed25519.h" 2 | #include "fe.h" 3 | 4 | void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) { 5 | unsigned char e[32]; 6 | unsigned int i; 7 | 8 | fe x1; 9 | fe x2; 10 | fe z2; 11 | fe x3; 12 | fe z3; 13 | fe tmp0; 14 | fe tmp1; 15 | 16 | int pos; 17 | unsigned int swap; 18 | unsigned int b; 19 | 20 | /* copy the private key and make sure it's valid */ 21 | for (i = 0; i < 32; ++i) { 22 | e[i] = private_key[i]; 23 | } 24 | 25 | e[0] &= 248; 26 | e[31] &= 63; 27 | e[31] |= 64; 28 | 29 | /* unpack the public key and convert edwards to montgomery */ 30 | /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */ 31 | fe_frombytes(x1, public_key); 32 | fe_1(tmp1); 33 | fe_add(tmp0, x1, tmp1); 34 | fe_sub(tmp1, tmp1, x1); 35 | fe_invert(tmp1, tmp1); 36 | fe_mul(x1, tmp0, tmp1); 37 | 38 | fe_1(x2); 39 | fe_0(z2); 40 | fe_copy(x3, x1); 41 | fe_1(z3); 42 | 43 | swap = 0; 44 | for (pos = 254; pos >= 0; --pos) { 45 | b = e[pos / 8] >> (pos & 7); 46 | b &= 1; 47 | swap ^= b; 48 | fe_cswap(x2, x3, swap); 49 | fe_cswap(z2, z3, swap); 50 | swap = b; 51 | 52 | /* from montgomery.h */ 53 | fe_sub(tmp0, x3, z3); 54 | fe_sub(tmp1, x2, z2); 55 | fe_add(x2, x2, z2); 56 | fe_add(z2, x3, z3); 57 | fe_mul(z3, tmp0, x2); 58 | fe_mul(z2, z2, tmp1); 59 | fe_sq(tmp0, tmp1); 60 | fe_sq(tmp1, x2); 61 | fe_add(x3, z3, z2); 62 | fe_sub(z2, z3, z2); 63 | fe_mul(x2, tmp1, tmp0); 64 | fe_sub(tmp1, tmp1, tmp0); 65 | fe_sq(z2, z2); 66 | fe_mul121666(z3, tmp1); 67 | fe_sq(x3, x3); 68 | fe_add(tmp0, tmp0, z3); 69 | fe_mul(z3, x1, z2); 70 | fe_mul(z2, tmp1, tmp0); 71 | } 72 | 73 | fe_cswap(x2, x3, swap); 74 | fe_cswap(z2, z3, swap); 75 | 76 | fe_invert(z2, z2); 77 | fe_mul(x2, x2, z2); 78 | fe_tobytes(shared_secret, x2); 79 | } 80 | -------------------------------------------------------------------------------- /components/ed25519/keypair.c: -------------------------------------------------------------------------------- 1 | #include "ed25519.h" 2 | #include "sha512.h" 3 | #include "ge.h" 4 | 5 | 6 | void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) { 7 | ge_p3 A; 8 | 9 | sha512(seed, 32, private_key); 10 | private_key[0] &= 248; 11 | private_key[31] &= 63; 12 | private_key[31] |= 64; 13 | 14 | ge_scalarmult_base(&A, private_key); 15 | ge_p3_tobytes(public_key, &A); 16 | } 17 | -------------------------------------------------------------------------------- /components/ed25519/sc.h: -------------------------------------------------------------------------------- 1 | #ifndef SC_H 2 | #define SC_H 3 | 4 | /* 5 | The set of scalars is \Z/l 6 | where l = 2^252 + 27742317777372353535851937790883648493. 7 | */ 8 | 9 | void sc_reduce(unsigned char *s); 10 | void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /components/ed25519/seed.c: -------------------------------------------------------------------------------- 1 | #include "ed25519.h" 2 | 3 | #ifndef ED25519_NO_SEED 4 | 5 | #ifdef _WIN32 6 | #include 7 | #include 8 | #else 9 | #include 10 | #endif 11 | 12 | int ed25519_create_seed(unsigned char *seed) { 13 | #ifdef _WIN32 14 | HCRYPTPROV prov; 15 | 16 | if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { 17 | return 1; 18 | } 19 | 20 | if (!CryptGenRandom(prov, 32, seed)) { 21 | CryptReleaseContext(prov, 0); 22 | return 1; 23 | } 24 | 25 | CryptReleaseContext(prov, 0); 26 | #else 27 | FILE *f = fopen("/dev/urandom", "rb"); 28 | 29 | if (f == NULL) { 30 | return 1; 31 | } 32 | 33 | fread(seed, 1, 32, f); 34 | fclose(f); 35 | #endif 36 | 37 | return 0; 38 | } 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /components/ed25519/sha512.h: -------------------------------------------------------------------------------- 1 | #ifndef SHA512_H 2 | #define SHA512_H 3 | 4 | #include 5 | 6 | #include "fixedint.h" 7 | 8 | /* state */ 9 | typedef struct sha512_context_ { 10 | uint64_t length, state[8]; 11 | size_t curlen; 12 | unsigned char buf[128]; 13 | } sha512_context; 14 | 15 | 16 | int sha512_init(sha512_context * md); 17 | int sha512_final(sha512_context * md, unsigned char *out); 18 | int sha512_update(sha512_context * md, const unsigned char *in, size_t inlen); 19 | int sha512(const unsigned char *message, size_t message_len, unsigned char *out); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /components/ed25519/sign.c: -------------------------------------------------------------------------------- 1 | #include "ed25519.h" 2 | #include "sha512.h" 3 | #include "ge.h" 4 | #include "sc.h" 5 | 6 | 7 | void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) { 8 | sha512_context hash; 9 | unsigned char hram[64]; 10 | unsigned char r[64]; 11 | ge_p3 R; 12 | 13 | 14 | sha512_init(&hash); 15 | sha512_update(&hash, private_key + 32, 32); 16 | sha512_update(&hash, message, message_len); 17 | sha512_final(&hash, r); 18 | 19 | sc_reduce(r); 20 | ge_scalarmult_base(&R, r); 21 | ge_p3_tobytes(signature, &R); 22 | 23 | sha512_init(&hash); 24 | sha512_update(&hash, signature, 32); 25 | sha512_update(&hash, public_key, 32); 26 | sha512_update(&hash, message, message_len); 27 | sha512_final(&hash, hram); 28 | 29 | sc_reduce(hram); 30 | sc_muladd(signature + 32, hram, private_key, r); 31 | } 32 | -------------------------------------------------------------------------------- /components/ed25519/verify.c: -------------------------------------------------------------------------------- 1 | #include "ed25519.h" 2 | #include "sha512.h" 3 | #include "ge.h" 4 | #include "sc.h" 5 | 6 | static int consttime_equal(const unsigned char *x, const unsigned char *y) { 7 | unsigned char r = 0; 8 | 9 | r = x[0] ^ y[0]; 10 | #define F(i) r |= x[i] ^ y[i] 11 | F(1); 12 | F(2); 13 | F(3); 14 | F(4); 15 | F(5); 16 | F(6); 17 | F(7); 18 | F(8); 19 | F(9); 20 | F(10); 21 | F(11); 22 | F(12); 23 | F(13); 24 | F(14); 25 | F(15); 26 | F(16); 27 | F(17); 28 | F(18); 29 | F(19); 30 | F(20); 31 | F(21); 32 | F(22); 33 | F(23); 34 | F(24); 35 | F(25); 36 | F(26); 37 | F(27); 38 | F(28); 39 | F(29); 40 | F(30); 41 | F(31); 42 | #undef F 43 | 44 | return !r; 45 | } 46 | 47 | int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) { 48 | unsigned char h[64]; 49 | unsigned char checker[32]; 50 | sha512_context hash; 51 | ge_p3 A; 52 | ge_p2 R; 53 | 54 | if (signature[63] & 224) { 55 | return 0; 56 | } 57 | 58 | if (ge_frombytes_negate_vartime(&A, public_key) != 0) { 59 | return 0; 60 | } 61 | 62 | sha512_init(&hash); 63 | sha512_update(&hash, signature, 32); 64 | sha512_update(&hash, public_key, 32); 65 | sha512_update(&hash, message, message_len); 66 | sha512_final(&hash, h); 67 | 68 | sc_reduce(h); 69 | ge_double_scalarmult_vartime(&R, h, &A, signature + 32); 70 | ge_tobytes(checker, &R); 71 | 72 | if (!consttime_equal(checker, signature)) { 73 | return 0; 74 | } 75 | 76 | return 1; 77 | } 78 | -------------------------------------------------------------------------------- /components/graph/component.mk: -------------------------------------------------------------------------------- 1 | # Component Makefile 2 | 3 | COMPONENT_ADD_INCLUDEDIRS := . 4 | 5 | -------------------------------------------------------------------------------- /components/graph/font.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "font.h" 7 | #include "font_16px.h" 8 | #include "font_8px.h" 9 | 10 | static inline void 11 | draw_pixel(uint8_t *buf, int x, int y, int c) 12 | { 13 | if (x < 0 || x > 295 || y < 0 || y > 127) 14 | return; 15 | int pos = (x >> 3) + y * (296 / 8); 16 | if (c < 128) 17 | buf[pos] &= 0xff - (1 << (x&7)); 18 | else 19 | buf[pos] |= (1 << (x&7)); 20 | } 21 | 22 | static inline void 23 | draw_pixel_8b(uint8_t *buf, int x, int y, int c) 24 | { 25 | if (x < 0 || x > 295 || y < 0 || y > 127) 26 | return; 27 | int pos = x + y * 296; 28 | buf[pos] = c; 29 | } 30 | 31 | int 32 | draw_font(uint8_t *buf, int x, int y, int x_len, const char *text, uint8_t flags) { 33 | // select font definitions 34 | const uint8_t *font_data; 35 | const uint8_t *font_width; 36 | int font_FIRST, font_LAST, font_WIDTH, font_HEIGHT; 37 | 38 | if (flags & FONT_16PX) { 39 | font_data = font_16px_data; 40 | font_width = font_16px_width; 41 | font_FIRST = FONT_16PX_FIRST; 42 | font_LAST = FONT_16PX_LAST; 43 | font_WIDTH = FONT_16PX_WIDTH; 44 | font_HEIGHT = FONT_16PX_HEIGHT; 45 | } else { 46 | font_data = font_8px_data; 47 | font_width = font_8px_width; 48 | font_FIRST = FONT_8PX_FIRST; 49 | font_LAST = FONT_8PX_LAST; 50 | font_WIDTH = FONT_8PX_WIDTH; 51 | font_HEIGHT = FONT_8PX_HEIGHT; 52 | } 53 | 54 | int x_max = x_len + x; 55 | 56 | uint8_t ch_ul = 0x00; 57 | if (flags & FONT_UNDERLINE_1) 58 | ch_ul |= 0x80; 59 | if (flags & FONT_UNDERLINE_2) 60 | ch_ul |= 0x40; 61 | 62 | int numChars = 0; 63 | while (*text != 0 && x < x_max) { 64 | int ch = *text; 65 | if (ch < font_FIRST || ch > font_LAST) 66 | ch = 0; 67 | else 68 | ch -= font_FIRST; 69 | 70 | uint8_t ch_width; 71 | unsigned int f_index = ch * (font_WIDTH * font_HEIGHT); 72 | if (flags & FONT_MONOSPACE) { 73 | ch_width = font_WIDTH; 74 | } else { 75 | ch_width = font_width[ch]; 76 | f_index += (ch_width >> 4) * font_HEIGHT; 77 | ch_width &= 0x0f; 78 | } 79 | 80 | if (x + ch_width >= x_max) 81 | break; // not enough space for full character 82 | 83 | while (ch_width > 0 && x < x_max) { 84 | int ch_y; 85 | for (ch_y = 0; ch_y < font_HEIGHT; ch_y++) { 86 | uint8_t ch = font_data[f_index++]; 87 | if (flags & FONT_INVERT) 88 | ch = ~ch; 89 | ch ^= (ch_y == 0 ? ch_ul : 0); 90 | 91 | int ch_y2; 92 | for (ch_y2=0; ch_y2<8; ch_y2++) 93 | { 94 | draw_pixel(buf, x, y + (font_HEIGHT-ch_y-1)*8 + ch_y2, (ch & 1) ? 255 : 0); 95 | ch >>= 1; 96 | } 97 | } 98 | x++; 99 | ch_width--; 100 | } 101 | text = &text[1]; 102 | numChars++; 103 | } 104 | 105 | if (flags & FONT_FULL_WIDTH) { 106 | uint8_t ch = 0; 107 | if (flags & FONT_INVERT) 108 | ch = ~ch; 109 | while (x < x_max) { 110 | int ch_y; 111 | for (ch_y = 0; ch_y < font_HEIGHT; ch_y++) 112 | { 113 | uint8_t ch2 = ch; 114 | ch2 = ch ^ (ch_y == 0 ? ch_ul : 0); 115 | 116 | int ch_y2; 117 | for (ch_y2=0; ch_y2<8; ch_y2++) 118 | { 119 | draw_pixel(buf, x, y + (font_HEIGHT-ch_y-1)*8 + ch_y2, (ch2 & 1) ? 255 : 0); 120 | ch2 >>= 1; 121 | } 122 | } 123 | x++; 124 | } 125 | } 126 | 127 | return numChars; 128 | } 129 | -------------------------------------------------------------------------------- /components/graph/font.h: -------------------------------------------------------------------------------- 1 | #ifndef EPD_FONT_H 2 | #define EPD_FONT_H 3 | 4 | #include 5 | #include 6 | 7 | #define FONT_16PX 0x01 8 | #define FONT_INVERT 0x02 9 | #define FONT_FULL_WIDTH 0x04 10 | #define FONT_MONOSPACE 0x08 11 | #define FONT_UNDERLINE_1 0x10 12 | #define FONT_UNDERLINE_2 0x20 13 | 14 | extern int 15 | draw_font(uint8_t *buf, int x, int y, int x_len, const char *text, uint8_t flags); 16 | 17 | #endif // EPD_FONT_H 18 | -------------------------------------------------------------------------------- /components/graph/font_16px.h: -------------------------------------------------------------------------------- 1 | #ifndef FONT_16PX_H 2 | #define FONT_16PX_H 3 | 4 | #include 5 | 6 | #define FONT_16PX_FIRST 32 7 | #define FONT_16PX_LAST 126 8 | #define FONT_16PX_WIDTH 12 9 | #define FONT_16PX_HEIGHT 2 10 | 11 | extern const uint8_t font_16px_data[2280]; 12 | extern const uint8_t font_16px_width[95]; 13 | 14 | #endif // FONT_16PX_H 15 | -------------------------------------------------------------------------------- /components/graph/font_8px.h: -------------------------------------------------------------------------------- 1 | #ifndef FONT_8PX_H 2 | #define FONT_8PX_H 3 | 4 | #include 5 | 6 | #define FONT_8PX_FIRST 32 7 | #define FONT_8PX_LAST 126 8 | #define FONT_8PX_WIDTH 6 9 | #define FONT_8PX_HEIGHT 1 10 | 11 | extern const uint8_t font_8px_data[570]; 12 | extern const uint8_t font_8px_width[95]; 13 | 14 | #endif // FONT_8PX_H 15 | -------------------------------------------------------------------------------- /components/png/adler32.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "adler32.h" 5 | 6 | uint32_t 7 | lib_adler32(const uint8_t *buf, size_t buf_len, uint32_t adler) 8 | { 9 | uint32_t adler_a = adler & 0xffff; 10 | uint32_t adler_b = adler >> 16; 11 | 12 | while (buf_len > 5552) 13 | { 14 | int sub_len = 5552; 15 | while (sub_len-- > 0) 16 | { 17 | adler_a += *buf++; 18 | adler_b += adler_a; 19 | } 20 | buf_len -= 5552; 21 | adler_a %= 65521; 22 | adler_b %= 65521; 23 | } 24 | 25 | while (buf_len-- > 0) 26 | { 27 | adler_a += *buf++; 28 | adler_b += adler_a; 29 | } 30 | 31 | adler_a %= 65521; 32 | adler_b %= 65521; 33 | 34 | return (adler_b << 16) | adler_a; 35 | } 36 | -------------------------------------------------------------------------------- /components/png/adler32.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_ADLER32_H 2 | #define LIB_ADLER32_H 3 | 4 | #include 5 | #include 6 | 7 | #define LIB_ADLER32_INIT 1 8 | 9 | extern uint32_t lib_adler32(const uint8_t *buf, size_t buf_len, uint32_t adler); 10 | 11 | #endif // LIB_ADLER32_H 12 | -------------------------------------------------------------------------------- /components/png/component.mk: -------------------------------------------------------------------------------- 1 | # Component Makefile 2 | 3 | COMPONENT_ADD_INCLUDEDIRS := . 4 | 5 | -------------------------------------------------------------------------------- /components/png/crc32.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "crc32.h" 5 | 6 | #define USE_ESP32_ROM_CRC32 7 | 8 | #ifdef USE_ESP32_ROM_CRC32 9 | 10 | #include 11 | #include 12 | uint32_t 13 | lib_crc32(const uint8_t *buf, size_t buf_len, uint32_t crc) 14 | { 15 | return crc32_le(crc, buf, buf_len); 16 | } 17 | 18 | #else 19 | 20 | static const uint32_t lib_crc32_lookup[256] = { 21 | 0x00000000,0x77073096,0xee0e612c,0x990951ba,0x076dc419,0x706af48f,0xe963a535,0x9e6495a3, 22 | 0x0edb8832,0x79dcb8a4,0xe0d5e91e,0x97d2d988,0x09b64c2b,0x7eb17cbd,0xe7b82d07,0x90bf1d91, 23 | 0x1db71064,0x6ab020f2,0xf3b97148,0x84be41de,0x1adad47d,0x6ddde4eb,0xf4d4b551,0x83d385c7, 24 | 0x136c9856,0x646ba8c0,0xfd62f97a,0x8a65c9ec,0x14015c4f,0x63066cd9,0xfa0f3d63,0x8d080df5, 25 | 0x3b6e20c8,0x4c69105e,0xd56041e4,0xa2677172,0x3c03e4d1,0x4b04d447,0xd20d85fd,0xa50ab56b, 26 | 0x35b5a8fa,0x42b2986c,0xdbbbc9d6,0xacbcf940,0x32d86ce3,0x45df5c75,0xdcd60dcf,0xabd13d59, 27 | 0x26d930ac,0x51de003a,0xc8d75180,0xbfd06116,0x21b4f4b5,0x56b3c423,0xcfba9599,0xb8bda50f, 28 | 0x2802b89e,0x5f058808,0xc60cd9b2,0xb10be924,0x2f6f7c87,0x58684c11,0xc1611dab,0xb6662d3d, 29 | 0x76dc4190,0x01db7106,0x98d220bc,0xefd5102a,0x71b18589,0x06b6b51f,0x9fbfe4a5,0xe8b8d433, 30 | 0x7807c9a2,0x0f00f934,0x9609a88e,0xe10e9818,0x7f6a0dbb,0x086d3d2d,0x91646c97,0xe6635c01, 31 | 0x6b6b51f4,0x1c6c6162,0x856530d8,0xf262004e,0x6c0695ed,0x1b01a57b,0x8208f4c1,0xf50fc457, 32 | 0x65b0d9c6,0x12b7e950,0x8bbeb8ea,0xfcb9887c,0x62dd1ddf,0x15da2d49,0x8cd37cf3,0xfbd44c65, 33 | 0x4db26158,0x3ab551ce,0xa3bc0074,0xd4bb30e2,0x4adfa541,0x3dd895d7,0xa4d1c46d,0xd3d6f4fb, 34 | 0x4369e96a,0x346ed9fc,0xad678846,0xda60b8d0,0x44042d73,0x33031de5,0xaa0a4c5f,0xdd0d7cc9, 35 | 0x5005713c,0x270241aa,0xbe0b1010,0xc90c2086,0x5768b525,0x206f85b3,0xb966d409,0xce61e49f, 36 | 0x5edef90e,0x29d9c998,0xb0d09822,0xc7d7a8b4,0x59b33d17,0x2eb40d81,0xb7bd5c3b,0xc0ba6cad, 37 | 0xedb88320,0x9abfb3b6,0x03b6e20c,0x74b1d29a,0xead54739,0x9dd277af,0x04db2615,0x73dc1683, 38 | 0xe3630b12,0x94643b84,0x0d6d6a3e,0x7a6a5aa8,0xe40ecf0b,0x9309ff9d,0x0a00ae27,0x7d079eb1, 39 | 0xf00f9344,0x8708a3d2,0x1e01f268,0x6906c2fe,0xf762575d,0x806567cb,0x196c3671,0x6e6b06e7, 40 | 0xfed41b76,0x89d32be0,0x10da7a5a,0x67dd4acc,0xf9b9df6f,0x8ebeeff9,0x17b7be43,0x60b08ed5, 41 | 0xd6d6a3e8,0xa1d1937e,0x38d8c2c4,0x4fdff252,0xd1bb67f1,0xa6bc5767,0x3fb506dd,0x48b2364b, 42 | 0xd80d2bda,0xaf0a1b4c,0x36034af6,0x41047a60,0xdf60efc3,0xa867df55,0x316e8eef,0x4669be79, 43 | 0xcb61b38c,0xbc66831a,0x256fd2a0,0x5268e236,0xcc0c7795,0xbb0b4703,0x220216b9,0x5505262f, 44 | 0xc5ba3bbe,0xb2bd0b28,0x2bb45a92,0x5cb36a04,0xc2d7ffa7,0xb5d0cf31,0x2cd99e8b,0x5bdeae1d, 45 | 0x9b64c2b0,0xec63f226,0x756aa39c,0x026d930a,0x9c0906a9,0xeb0e363f,0x72076785,0x05005713, 46 | 0x95bf4a82,0xe2b87a14,0x7bb12bae,0x0cb61b38,0x92d28e9b,0xe5d5be0d,0x7cdcefb7,0x0bdbdf21, 47 | 0x86d3d2d4,0xf1d4e242,0x68ddb3f8,0x1fda836e,0x81be16cd,0xf6b9265b,0x6fb077e1,0x18b74777, 48 | 0x88085ae6,0xff0f6a70,0x66063bca,0x11010b5c,0x8f659eff,0xf862ae69,0x616bffd3,0x166ccf45, 49 | 0xa00ae278,0xd70dd2ee,0x4e048354,0x3903b3c2,0xa7672661,0xd06016f7,0x4969474d,0x3e6e77db, 50 | 0xaed16a4a,0xd9d65adc,0x40df0b66,0x37d83bf0,0xa9bcae53,0xdebb9ec5,0x47b2cf7f,0x30b5ffe9, 51 | 0xbdbdf21c,0xcabac28a,0x53b39330,0x24b4a3a6,0xbad03605,0xcdd70693,0x54de5729,0x23d967bf, 52 | 0xb3667a2e,0xc4614ab8,0x5d681b02,0x2a6f2b94,0xb40bbe37,0xc30c8ea1,0x5a05df1b,0x2d02ef8d 53 | }; 54 | 55 | uint32_t 56 | lib_crc32(const uint8_t *buf, size_t buf_len, uint32_t crc) 57 | { 58 | crc ^= 0xffffffff; 59 | 60 | while (buf_len-- > 0) 61 | { 62 | crc = lib_crc32_lookup[(crc ^ *buf++) & 0xff] ^ (crc >> 8); 63 | } 64 | 65 | return crc ^ 0xffffffff; 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /components/png/crc32.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_CRC32_H 2 | #define LIB_CRC32_H 3 | 4 | #include 5 | #include 6 | 7 | #define LIB_CRC32_INIT 0 8 | 9 | extern uint32_t lib_crc32(const uint8_t *buf, size_t buf_len, uint32_t crc); 10 | 11 | #endif // LIB_CRC32_H 12 | -------------------------------------------------------------------------------- /components/png/deflate_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_DEFLATE_READER_H 2 | #define LIB_DEFLATE_READER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "reader.h" 9 | 10 | enum lib_deflate_state_t { 11 | LIB_DEFLATE_STATE_NEW_BLOCK = 0, 12 | LIB_DEFLATE_STATE_STORED_BLOCK, 13 | LIB_DEFLATE_STATE_HUFFMAN, 14 | LIB_DEFLATE_STATE_HUFFMAN_REPEAT, 15 | }; 16 | 17 | enum lib_deflate_error_t { 18 | LIB_DEFLATE_ERROR_BASE = 0x1000, 19 | LIB_DEFLATE_ERROR_UNEXPECTED_END_OF_FILE, 20 | LIB_DEFLATE_ERROR_UNBALANCED_HUFFMAN_TREE, 21 | LIB_DEFLATE_ERROR_INVALID_COPY_LENGTH, 22 | LIB_DEFLATE_ERROR_RESERVED_BLOCK_TYPE, 23 | LIB_DEFLATE_ERROR_DYNAMIC_HUFFMAN_SETUP_ERROR, 24 | LIB_DEFLATE_ERROR_HUFFMAN_RESERVED_LENGTH, 25 | LIB_DEFLATE_ERROR_HUFFMAN_INVALID_DISTANCE, 26 | LIB_DEFLATE_ERROR_TOP, 27 | }; 28 | 29 | struct lib_deflate_reader { 30 | lib_reader_read_t read; 31 | void *read_p; 32 | 33 | uint8_t bitbuf[2]; 34 | uint8_t bitlen; 35 | 36 | bool is_last_block; 37 | enum lib_deflate_state_t state; 38 | uint8_t look_behind[32768]; 39 | int lb_size; 40 | int lb_pos; 41 | 42 | int copy_dist; 43 | int copy_len; 44 | 45 | uint16_t huffman_lc_tree[288+15]; 46 | uint16_t huffman_dc_tree[32+15]; 47 | }; 48 | 49 | extern struct lib_deflate_reader * lib_deflate_new(lib_reader_read_t read, void *read_p); 50 | extern void lib_deflate_init(struct lib_deflate_reader *dr, lib_reader_read_t read, void *read_p); 51 | extern ssize_t lib_deflate_read(struct lib_deflate_reader *dr, uint8_t *buf, size_t buf_len); 52 | extern void lib_deflate_destroy(struct lib_deflate_reader *dr); 53 | 54 | #endif // LIB_DEFLATE_READER_H 55 | -------------------------------------------------------------------------------- /components/png/file_reader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "file_reader.h" 8 | 9 | struct lib_file_reader * 10 | lib_file_new(const char *filename, int bufsize) 11 | { 12 | int fd = open(filename, O_RDONLY); 13 | if (fd == -1) 14 | return NULL; 15 | 16 | struct lib_file_reader *fr = (struct lib_file_reader *) malloc(sizeof(struct lib_file_reader) + bufsize); 17 | if (fr == NULL) 18 | return NULL; 19 | 20 | memset(fr, 0, sizeof(struct lib_file_reader) + bufsize); 21 | fr->fd = fd; 22 | fr->bufsize = bufsize; 23 | 24 | return fr; 25 | } 26 | 27 | ssize_t 28 | lib_file_read(struct lib_file_reader *fr, uint8_t *buf, size_t buf_len) 29 | { 30 | ssize_t res = 0; 31 | while (buf_len > 0) 32 | { 33 | if (fr->buflen == 0) 34 | { 35 | ssize_t r = read(fr->fd, fr->buf, fr->bufsize); 36 | if (r < 0) 37 | return r; 38 | if (r == 0) 39 | return res; 40 | fr->bufpos = 0; 41 | fr->buflen = r; 42 | } 43 | 44 | if (fr->buflen) 45 | { 46 | ssize_t maxcopy = fr->buflen > buf_len ? buf_len : fr->buflen; 47 | memcpy(buf, &fr->buf[fr->bufpos], maxcopy); 48 | buf = &buf[maxcopy]; 49 | buf_len -= maxcopy; 50 | res += maxcopy; 51 | fr->bufpos += maxcopy; 52 | fr->buflen -= maxcopy; 53 | } 54 | } 55 | 56 | return res; 57 | } 58 | 59 | void 60 | lib_file_destroy(struct lib_file_reader *fr) 61 | { 62 | if (fr->fd) 63 | close(fr->fd); 64 | free(fr); 65 | } 66 | -------------------------------------------------------------------------------- /components/png/file_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_FILE_READER_H 2 | #define LIB_FILE_READER_H 3 | 4 | #include 5 | #include 6 | 7 | struct lib_file_reader { 8 | int fd; 9 | int bufsize; 10 | int buflen; 11 | int bufpos; 12 | uint8_t buf[0]; 13 | }; 14 | 15 | extern struct lib_file_reader * lib_file_new(const char *filename, int bufsize); 16 | extern ssize_t lib_file_read(struct lib_file_reader *fr, uint8_t *buf, size_t buf_len); 17 | extern void lib_file_destroy(struct lib_file_reader *fr); 18 | 19 | #endif // LIB_FILE_READER_H 20 | -------------------------------------------------------------------------------- /components/png/flash_reader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "flash_reader.h" 10 | 11 | struct lib_flash_reader * 12 | lib_flash_new(const esp_partition_t *part, size_t offset) 13 | { 14 | struct lib_flash_reader *fr = (struct lib_flash_reader *) malloc(sizeof(struct lib_flash_reader)); 15 | if (fr == NULL) 16 | return NULL; 17 | 18 | memset(fr, 0, sizeof(struct lib_flash_reader)); 19 | fr->part = part; 20 | fr->offset = offset; 21 | 22 | return fr; 23 | } 24 | 25 | ssize_t 26 | lib_flash_read(struct lib_flash_reader *fr, uint8_t *buf, size_t buf_len) 27 | { 28 | ssize_t res = 0; 29 | while (buf_len > 0) 30 | { 31 | if (fr->buflen == 0) 32 | { 33 | int offset = fr->offset & (SPI_FLASH_SEC_SIZE-1); 34 | fr->offset &= ~(SPI_FLASH_SEC_SIZE-1); 35 | 36 | esp_err_t err = esp_partition_read(fr->part, fr->offset, fr->buf, SPI_FLASH_SEC_SIZE); 37 | if (err != ESP_OK) 38 | return -1; 39 | 40 | fr->bufpos = offset; 41 | fr->buflen = SPI_FLASH_SEC_SIZE - offset; 42 | fr->offset += SPI_FLASH_SEC_SIZE; 43 | } 44 | 45 | if (fr->buflen) 46 | { 47 | ssize_t maxcopy = fr->buflen > buf_len ? buf_len : fr->buflen; 48 | memcpy(buf, &fr->buf[fr->bufpos], maxcopy); 49 | buf = &buf[maxcopy]; 50 | buf_len -= maxcopy; 51 | res += maxcopy; 52 | fr->bufpos += maxcopy; 53 | fr->buflen -= maxcopy; 54 | } 55 | } 56 | 57 | return res; 58 | } 59 | 60 | void 61 | lib_flash_destroy(struct lib_flash_reader *fr) 62 | { 63 | free(fr); 64 | } 65 | -------------------------------------------------------------------------------- /components/png/flash_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_FLASH_READER_H 2 | #define LIB_FLASH_READER_H 3 | 4 | #include 5 | #include 6 | 7 | struct lib_flash_reader { 8 | const esp_partition_t *part; 9 | size_t offset; 10 | int buflen; 11 | int bufpos; 12 | uint8_t buf[SPI_FLASH_SEC_SIZE]; 13 | }; 14 | 15 | extern struct lib_flash_reader * lib_flash_new(const esp_partition_t *part, size_t offset); 16 | extern ssize_t lib_flash_read(struct lib_flash_reader *fr, uint8_t *buf, size_t buf_len); 17 | extern void lib_flash_destroy(struct lib_flash_reader *fr); 18 | 19 | #endif // LIB_FLASH_READER_H 20 | -------------------------------------------------------------------------------- /components/png/mem_reader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "mem_reader.h" 8 | 9 | struct lib_mem_reader * 10 | lib_mem_new(const uint8_t *data, size_t len) 11 | { 12 | struct lib_mem_reader *mr = (struct lib_mem_reader *) malloc(sizeof(struct lib_mem_reader)); 13 | if (mr == NULL) 14 | return NULL; 15 | 16 | memset(mr, 0, sizeof(struct lib_mem_reader)); 17 | mr->data = data; 18 | mr->len = len; 19 | 20 | return mr; 21 | } 22 | 23 | ssize_t 24 | lib_mem_read(struct lib_mem_reader *mr, uint8_t *buf, size_t buf_len) 25 | { 26 | ssize_t len = mr->len > buf_len ? buf_len : mr->len; 27 | 28 | memcpy(buf, mr->data, len); 29 | mr->data = &mr->data[len]; 30 | mr->len -= len; 31 | 32 | return len; 33 | } 34 | 35 | void 36 | lib_mem_destroy(struct lib_mem_reader *mr) 37 | { 38 | free(mr); 39 | } 40 | -------------------------------------------------------------------------------- /components/png/mem_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_MEM_READER_H 2 | #define LIB_MEM_READER_H 3 | 4 | #include 5 | #include 6 | 7 | struct lib_mem_reader { 8 | const uint8_t *data; 9 | size_t len; 10 | }; 11 | 12 | extern struct lib_mem_reader * lib_mem_new(const uint8_t *data, size_t len); 13 | extern ssize_t lib_mem_read(struct lib_mem_reader *mr, uint8_t *buf, size_t buf_len); 14 | extern void lib_mem_destroy(struct lib_mem_reader *mr); 15 | 16 | #endif // LIB_MEM_READER_H 17 | -------------------------------------------------------------------------------- /components/png/png_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_PNG_READER_H 2 | #define LIB_PNG_READER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "reader.h" 9 | 10 | enum lib_png_error_t { 11 | LIB_PNG_ERROR_BASE = 0x1100, 12 | LIB_PNG_ERROR_OUT_OF_MEMORY, 13 | LIB_PNG_ERROR_MISSING_SIGNATURE, 14 | LIB_PNG_ERROR_UNEXPECTED_END_OF_FILE, 15 | LIB_PNG_ERROR_UNEXPECTED_END_OF_CHUNK, 16 | LIB_PNG_ERROR_CHUNK_TOO_LARGE, 17 | LIB_PNG_ERROR_INVALID_FIRST_CHUNK, 18 | LIB_PNG_ERROR_UNKNOWN_CRITICAL_CHUNK, 19 | LIB_PNG_ERROR_ADLER32_CHECKSUM_MISMATCH, 20 | LIB_PNG_ERROR_CRC32_CHECKSUM_MISMATCH, 21 | LIB_PNG_ERROR_INVALID_PNG_TYPE, 22 | LIB_PNG_ERROR_NO_PALETTE_FOUND, 23 | LIB_PNG_ERROR_MULTIPLE_PALETTES_FOUND, 24 | LIB_PNG_ERROR_PALETTE_NOT_ALLOWED_FOR_PNG_TYPE, 25 | LIB_PNG_ERROR_INVALID_PALETTE_SIZE, 26 | LIB_PNG_ERROR_INVALID_DEFLATE_HEADER, 27 | LIB_PNG_ERROR_INVALID_PNG_SCANLINE_TYPE, 28 | LIB_PNG_ERROR_TOP, 29 | }; 30 | 31 | struct lib_png_chunk { 32 | bool in_chunk; 33 | uint32_t type; 34 | uint32_t len; 35 | uint32_t crc; 36 | }; 37 | 38 | struct lib_png_ihdr { 39 | uint32_t width; 40 | uint32_t height; 41 | uint8_t bit_depth; 42 | uint8_t color_type; 43 | uint8_t compression_method; 44 | uint8_t filter_method; 45 | uint8_t interlace_method; 46 | } __attribute__((packed)); 47 | 48 | struct lib_png_reader { 49 | lib_reader_read_t read; 50 | void *read_p; 51 | 52 | struct lib_png_chunk chunk; 53 | struct lib_png_ihdr ihdr; 54 | 55 | uint8_t *palette; 56 | int palette_len; 57 | 58 | uint8_t scanline_bpp; // 1, 2, 3, 4, 6 or 8 59 | uint32_t scanline_width; 60 | uint8_t *scanline; // large enough for scanline + temp secondary scanline 61 | 62 | struct lib_deflate_reader *dr; 63 | uint32_t adler; 64 | }; 65 | 66 | extern struct lib_png_reader * lib_png_new(lib_reader_read_t read, void *read_p); 67 | extern int lib_png_read_header(struct lib_png_reader *pr); 68 | extern int lib_png_load_image(struct lib_png_reader *pr, uint8_t *dst, uint32_t dst_min_x, uint32_t dst_min_y, uint32_t dst_width, uint32_t dst_height, uint32_t dst_linelen); 69 | extern void lib_png_destroy(struct lib_png_reader *pr); 70 | 71 | #endif // LIB_PNG_READER_H 72 | -------------------------------------------------------------------------------- /components/png/reader.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_READER_H 2 | #define LIB_READER_H 3 | 4 | #include 5 | #include 6 | 7 | typedef ssize_t (*lib_reader_read_t)(void *, void *, size_t); 8 | 9 | #endif // LIB_READER_H 10 | -------------------------------------------------------------------------------- /components/redundancy/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Component Makefile 3 | # 4 | 5 | COMPONENT_ADD_INCLUDEDIRS := . 6 | COMPONENT_SRCDIRS := . 7 | COMPONENT_PRIV_INCLUDEDIRS := . 8 | 9 | CFLAGS := $(filter-out -O1 -O2 -Og,$(CFLAGS)) -O3 -------------------------------------------------------------------------------- /components/redundancy/redundancy.h: -------------------------------------------------------------------------------- 1 | #ifndef REDUNDANCY_H 2 | #define REDUNDANCY_H 3 | 4 | #include 5 | 6 | // define the size of our finite field (galois binary field) 7 | #define GBF_BITS 16 8 | 9 | /* used word-size and known-good polynomes */ 10 | #if GBF_BITS == 32 11 | typedef uint32_t gbf_int_t; 12 | // polynome: x^32 + x^7 + x^3 + x^2 + 1 13 | #define GBF_POLYNOME 0x8d 14 | 15 | #elif GBF_BITS == 16 16 | typedef uint16_t gbf_int_t; 17 | // polynome: x^16 + x^5 + x^3 + x + 1 18 | #define GBF_POLYNOME 0x2b 19 | 20 | #elif GBF_BITS == 8 21 | typedef uint8_t gbf_int_t; 22 | // polynome: x^8 + x^4 + x^3 + x + 1 23 | #define GBF_POLYNOME 0x1b 24 | #endif 25 | 26 | /* gbf_init(polynome); 27 | * Library needs to be initialized with a specific polynome. 28 | * 29 | * To initialize the library with the default known-good polynome, use: 30 | * gbf_init(GBF_POLYNOME); 31 | */ 32 | extern void gbf_init(gbf_int_t polynome); 33 | 34 | 35 | /*************************************************************************** 36 | ** basic operations on a word; ** 37 | ** no need to call them if you only use gbf_encode_one() and gbf_decode() ** 38 | ***************************************************************************/ 39 | 40 | /* gbf_mul(v1, v2) 41 | * Multiply two values with each other. (modulo given polynome) 42 | */ 43 | extern gbf_int_t gbf_mul(gbf_int_t v1, gbf_int_t v2); 44 | 45 | /* gbf_prw(v1, v2) 46 | * v1 to the power of v2. (modulo given polynome) 47 | */ 48 | extern gbf_int_t gbf_pwr(gbf_int_t v1, gbf_int_t v2); 49 | 50 | /* gbf_inv(v1) 51 | * The multiplicative inverse of v1. (modulo given polynome) 52 | */ 53 | extern gbf_int_t gbf_inv(gbf_int_t r); 54 | extern gbf_int_t gbf_inv_phi(gbf_int_t v1); // slower, alternative method 55 | 56 | /* gbf_invmatrix(matrix[size*size], size) 57 | * Calculate the inverse matrix. 58 | */ 59 | extern void gbf_invmatrix(gbf_int_t *matrix, int size); 60 | 61 | 62 | /*************************************************************************** 63 | ** encode and decode methods ** 64 | ***************************************************************************/ 65 | 66 | /* gbf_encode_one(out[size], data[num_frag*size], vec, num_frag, size) 67 | * Encode one packet. At least packets are needed to decode 68 | * the data. should be unique and is not allowed to be 0. 69 | */ 70 | extern void gbf_encode_one(gbf_int_t *out, gbf_int_t *data, gbf_int_t vec, int num_frag, int size); 71 | 72 | /* gbf_decode(out[num_frag*size], data[num_frag*size], vec[num_frag], num_frag, size) 73 | * Decode the original data. contains all concatenated fragments. 74 | * contains all used vector-values (should be in the same order as 75 | * the fragments). 76 | */ 77 | extern void gbf_decode(gbf_int_t *out, gbf_int_t *data, gbf_int_t *vec, int num_frag, int size); 78 | 79 | #endif // REDUNDANCY_H 80 | -------------------------------------------------------------------------------- /components/sha2017/GeoTrust_Global_CA.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/components/sha2017/GeoTrust_Global_CA.der -------------------------------------------------------------------------------- /components/sha2017/GeoTrust_Global_CA.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT 3 | MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i 4 | YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG 5 | EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg 6 | R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 7 | 9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq 8 | fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv 9 | iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU 10 | 1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ 11 | bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW 12 | MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA 13 | ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l 14 | uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn 15 | Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS 16 | tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF 17 | PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un 18 | hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV 19 | 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== 20 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /components/sha2017/Kconfig: -------------------------------------------------------------------------------- 1 | menu "SHA2017 Badge OTA" 2 | 3 | config OTA_SERVER_NAME 4 | string "OTA server name" 5 | default "badge.sha2017.org" 6 | help 7 | Hostname of the OTA server 8 | 9 | config OTA_SERVER_PATH 10 | string "OTA server path" 11 | default "/firmware" 12 | help 13 | The path on the OTA server 14 | 15 | endmenu 16 | -------------------------------------------------------------------------------- /components/sha2017/component.mk: -------------------------------------------------------------------------------- 1 | # Component Makefile 2 | 3 | COMPONENT_ADD_INCLUDEDIRS := . 4 | 5 | COMPONENT_EXTRA_INCLUDES := \ 6 | $(UGFX_PATH) \ 7 | $(UGFX_PATH)/drivers/gdisp/framebuffer \ 8 | $(IDF_PATH)/components/freertos/include/freertos \ 9 | 10 | -------------------------------------------------------------------------------- /components/sha2017/sha2017_ota.h: -------------------------------------------------------------------------------- 1 | #ifndef SHA2017_OTA_H 2 | #define SHA2017_OTA_H 3 | 4 | extern void sha2017_ota_update(void); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /components/sha2017/sha2017_ota_graphics.c: -------------------------------------------------------------------------------- 1 | 2 | #include "sdkconfig.h" 3 | 4 | #include 5 | 6 | #include "sha2017_ota_graphics.h" 7 | 8 | font_t permanentMarker36; 9 | font_t robotoBlackItalic; 10 | font_t permanentMarker; 11 | 12 | void sha2017_ota_percentage_init() { 13 | gfxInit(); 14 | 15 | robotoBlackItalic = gdispOpenFont("Roboto_BlackItalic24"); 16 | permanentMarker = gdispOpenFont("PermanentMarker22"); 17 | permanentMarker36 = gdispOpenFont("PermanentMarker36"); 18 | } 19 | 20 | void show_percentage(char *name, uint8_t percentage, bool show_percentage) { 21 | 22 | color_t front = White; 23 | color_t back = Black; 24 | 25 | gdispClear(back); 26 | 27 | if (show_percentage) { 28 | target_lut = 2; 29 | char perc[10]; 30 | sprintf(perc, "%d%%", percentage); 31 | gdispDrawString(30, 45, perc, permanentMarker36, front); 32 | } else { 33 | target_lut = 0; 34 | } 35 | 36 | gdispDrawString(show_percentage ? 150 : 60, 25, "STILL", robotoBlackItalic, front); 37 | gdispDrawString(show_percentage ? 130 : 40, 46, name, permanentMarker, front); 38 | // underline: 39 | gdispDrawLine(show_percentage ? 130 : 40, 72, 40 | (show_percentage ? 130 : 40) + gdispGetStringWidth(name, permanentMarker) + 14, 72, 41 | front); 42 | // cursor: 43 | gdispDrawLine((show_percentage ? 130 : 40) + gdispGetStringWidth(name, permanentMarker) + 10, 50 + 2, 44 | (show_percentage ? 130 : 40) + gdispGetStringWidth(name, permanentMarker) + 10, 50 + 22 - 2, 45 | front); 46 | gdispDrawString(140, 75, "Anyway", robotoBlackItalic, front); 47 | gdispFlush(); 48 | } 49 | -------------------------------------------------------------------------------- /components/sha2017/sha2017_ota_graphics.h: -------------------------------------------------------------------------------- 1 | #ifndef SHA2017_OTA_GRAPHICS_H 2 | #define SHA2017_OTA_GRAPHICS_H 3 | 4 | void show_percentage(char *name, uint8_t percentage, bool show_percentage); 5 | void sha2017_ota_percentage_init(); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /components/sha2017/wildcard_sha2017_org.h: -------------------------------------------------------------------------------- 1 | #ifndef WILDCARD_CERT_H 2 | #define WILDCARD_CERT_H 3 | 4 | extern const unsigned char wildcard_sha2017_org[]; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /components/ugfx-glue/Kconfig: -------------------------------------------------------------------------------- 1 | menu "uGFX" 2 | 3 | config SHA_BADGE_UGFX_GINPUT_DEBUG 4 | bool "Enable uGFX input debug messages" 5 | default n 6 | help 7 | Debugging 8 | 9 | endmenu 10 | -------------------------------------------------------------------------------- /components/ugfx-glue/PermanentMarker.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/components/ugfx-glue/PermanentMarker.ttf -------------------------------------------------------------------------------- /components/ugfx-glue/Roboto-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/components/ugfx-glue/Roboto-Black.ttf -------------------------------------------------------------------------------- /components/ugfx-glue/Roboto-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/components/ugfx-glue/Roboto-BlackItalic.ttf -------------------------------------------------------------------------------- /components/ugfx-glue/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/components/ugfx-glue/Roboto-Regular.ttf -------------------------------------------------------------------------------- /components/ugfx-glue/board_framebuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * GDISP framebuffer driver for our eink display, to bridge to ugfx. 3 | */ 4 | 5 | /* 6 | * This file is subject to the terms of the GFX License. If a copy of 7 | * the license was not distributed with this file, you can obtain one at: 8 | * 9 | * http://ugfx.org/license.html 10 | */ 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | // Set this to your frame buffer pixel format. 24 | #ifndef GDISP_LLD_PIXELFORMAT 25 | #define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_GRAY256 26 | #endif 27 | 28 | // Uncomment this if your frame buffer device requires flushing 29 | #define GDISP_HARDWARE_FLUSH TRUE 30 | 31 | // For now we simply keep the current state of the framebuffer in memory, and 32 | // encode it and send it to the badge_eink driver on flush 33 | uint8_t target_lut; 34 | 35 | #ifdef GDISP_DRIVER_VMT 36 | 37 | static void board_init(GDisplay *g, fbInfo *fbi) { 38 | uint8_t eink_type = BADGE_EINK_DEFAULT; 39 | badge_nvs_get_u8("badge", "eink.dev.type", &eink_type); 40 | esp_err_t err = badge_eink_init(eink_type); 41 | assert( err == ESP_OK ); 42 | 43 | err = badge_eink_fb_init(); 44 | assert( err == ESP_OK ); 45 | 46 | g->g.Width = BADGE_EINK_WIDTH; 47 | g->g.Height = BADGE_EINK_HEIGHT; 48 | g->g.Backlight = 100; 49 | g->g.Contrast = 50; 50 | fbi->linelen = g->g.Width; 51 | fbi->pixels = badge_eink_fb; 52 | target_lut = 2; 53 | } 54 | 55 | #if GDISP_HARDWARE_FLUSH 56 | bool ugfx_screen_flipped = false; 57 | static void board_flush(GDisplay *g) { 58 | (void) g; 59 | 60 | badge_eink_flags_t flags = DISPLAY_FLAG_8BITPIXEL; 61 | if (ugfx_screen_flipped) { 62 | flags |= DISPLAY_FLAG_ROTATE_180; 63 | } 64 | 65 | if (target_lut >= 0xf0) 66 | { 67 | // 0xf0 was used in some examples. support it for now.. 68 | badge_eink_display_greyscale(badge_eink_fb, flags, target_lut > 0xf0 ? target_lut - 0xf0 : BADGE_EINK_MAX_LAYERS); 69 | } 70 | else if (target_lut > BADGE_EINK_LUT_MAX) 71 | { 72 | badge_eink_display(badge_eink_fb, flags); 73 | } 74 | else 75 | { 76 | badge_eink_display(badge_eink_fb, flags | DISPLAY_FLAG_LUT(target_lut)); 77 | } 78 | } 79 | #endif 80 | 81 | #if GDISP_NEED_CONTROL 82 | static void board_backlight(GDisplay *g, uint8_t percent) { 83 | // TODO: Can be an empty function if your hardware doesn't support this 84 | (void) g; 85 | (void) percent; 86 | } 87 | 88 | static void board_contrast(GDisplay *g, uint8_t percent) { 89 | // TODO: Can be an empty function if your hardware doesn't support this 90 | (void) g; 91 | (void) percent; 92 | } 93 | 94 | static void board_power(GDisplay *g, powermode_t pwr) { 95 | // TODO: Can be an empty function if your hardware doesn't support this 96 | (void) g; 97 | (void) pwr; 98 | } 99 | #endif 100 | 101 | #endif /* GDISP_LLD_BOARD_IMPLEMENTATION */ 102 | -------------------------------------------------------------------------------- /components/ugfx-glue/build_fonts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x -e 4 | 5 | MCUFONTPATH=../../ugfx/tools/mcufontencoder/src/ 6 | 7 | make -C ${MCUFONTPATH} 8 | 9 | export PATH=${MCUFONTPATH}:$PATH 10 | 11 | # Path to the mcufont encoder program 12 | MCUFONT=mcufont 13 | 14 | # Character ranges to include in the fonts. 15 | # Default: ASCII only 16 | ASCIICHARS=32-127 17 | 18 | # Number of iterations in optimization 19 | # Higher numbers compress better 20 | ITERS=25 21 | 22 | FONTS_FILE=userfonts.h 23 | echo '// This file is generated by SHA2017-badge/Firmware/ugfx/build_fonts.sh' > ${FONTS_FILE} 24 | 25 | function build { 26 | infile=`basename $1` 27 | outfile=$2 28 | fmt=$3 29 | size=$4 30 | bw=$5 31 | ext="${infile##*.}" 32 | noext="${infile%.*}" 33 | chars=$6 34 | if [ $ext = 'ttf' ]; then 35 | dat=$noext$size$bw.dat 36 | cmd=import_ttf 37 | else 38 | dat=$noext.dat 39 | fi 40 | if [ ! -f $dat ]; then 41 | $MCUFONT $cmd $1 $size $bw 42 | $MCUFONT filter $dat $chars 43 | if [ $outfile = 'LargeNumbers' ]; then 44 | $MCUFONT filter $dat 0x20-0x39 45 | fi 46 | if [ $fmt = 'rlefont' ]; then 47 | $MCUFONT rlefont_optimize $dat $ITERS 48 | fi 49 | fi 50 | 51 | if [ $fmt = 'rlefont' ]; then 52 | $MCUFONT rlefont_export $dat $outfile.c 53 | else 54 | $MCUFONT bwfont_export $dat $outfile.c 55 | fi 56 | echo '#include "'$outfile.c'"' >> ${FONTS_FILE} 57 | } 58 | 59 | # Commands are of form: build [size] [bw] 60 | # If bw is not given, builds an antialiased font. 61 | 62 | build PermanentMarker.ttf fonts/PermanentMarker22 rlefont 22 '' ${ASCIICHARS} 63 | build PermanentMarker.ttf fonts/PermanentMarker36 rlefont 36 '' ${ASCIICHARS} 64 | build Roboto-Black.ttf fonts/Roboto-Black22 rlefont 22 '' ${ASCIICHARS} 65 | build Roboto-BlackItalic.ttf fonts/Roboto-BlackItalic24 rlefont 24 '' ${ASCIICHARS} 66 | build Roboto-Regular.ttf fonts/Roboto-Regular12 rlefont 12 '' ${ASCIICHARS} 67 | build Roboto-Regular.ttf fonts/Roboto-Regular18 rlefont 18 '' ${ASCIICHARS} 68 | build Roboto-Regular.ttf fonts/Roboto-Regular22 rlefont 22 '' ${ASCIICHARS} 69 | 70 | -------------------------------------------------------------------------------- /components/ugfx-glue/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Ugfx component makefile. 3 | # 4 | # This Makefile can be left empty. By default, it will take the sources in the 5 | # src/ directory, compile them and link them into lib(subdirectory_name).a 6 | # in the build directory. This behaviour is entirely configurable, 7 | # please read the ESP-IDF documents if you need to do this. 8 | # 9 | 10 | COMPONENT_ADD_INCLUDEDIRS := . 11 | 12 | COMPONENT_EXTRA_INCLUDES := \ 13 | $(UGFX_PATH) \ 14 | $(UGFX_PATH)/src \ 15 | $(UGFX_PATH)/src/gdisp/mcufont \ 16 | $(UGFX_PATH)/drivers/gdisp/framebuffer \ 17 | $(IDF_PATH)/components/freertos/include/freertos \ 18 | 19 | -------------------------------------------------------------------------------- /components/ugfx-glue/crunch_fonts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x -e 4 | ITERS=250 5 | 6 | MCUFONTPATH=../../ugfx/tools/mcufontencoder/src/ 7 | export PATH=${MCUFONTPATH}:$PATH 8 | 9 | for file in *.dat; do 10 | mcufont rlefont_optimize $file $ITERS 11 | done 12 | -------------------------------------------------------------------------------- /components/ugfx-glue/gfx_mk.c: -------------------------------------------------------------------------------- 1 | ../../ugfx/src/gfx_mk.c -------------------------------------------------------------------------------- /components/ugfx-glue/gfx_userfs.c: -------------------------------------------------------------------------------- 1 | #include "gfx_userfs.h" 2 | 3 | bool_t userfs_del(const char * fname){ 4 | if(!unlink(fname)){ 5 | return 1; 6 | } 7 | return 0; 8 | } 9 | 10 | bool_t userfs_exists(const char * fname){ 11 | struct stat statbuf; 12 | if(stat(fname, &statbuf) == 0){ 13 | return 1; 14 | } 15 | return 0; 16 | } 17 | 18 | long int userfs_filesize(const char * fname){ 19 | struct stat statbuf; 20 | if(stat(fname, &statbuf) == 0){ 21 | return statbuf.st_size; 22 | } 23 | return 0; 24 | } 25 | 26 | bool_t userfs_ren(const char * oldname, const char * newname){ 27 | return rename(oldname, newname) != -1; 28 | } 29 | 30 | bool_t userfs_open(GFILE *f, const char * fname){ 31 | switch(f->flags){ 32 | case GFILEFLG_READ: 33 | f->obj = fopen(fname, "r"); 34 | break; 35 | case GFILEFLG_WRITE: 36 | f->obj = fopen(fname, "w"); 37 | break; 38 | case GFILEFLG_READ|GFILEFLG_WRITE: 39 | f->obj = fopen(fname, "rw"); 40 | break; 41 | case GFILEFLG_WRITE|GFILEFLG_APPEND: 42 | f->obj = fopen(fname, "wa"); 43 | break; 44 | default: 45 | f->obj = fopen(fname, "rw"); 46 | break; 47 | /*return 0;*/ 48 | } 49 | if(f->obj != NULL){ 50 | f->flags |= GFILEFLG_OPEN; 51 | return 1; 52 | } 53 | return 0; 54 | } 55 | 56 | void userfs_close(GFILE *f){ 57 | if(f->obj){ 58 | fclose(f->obj); 59 | f->flags &= ~GFILEFLG_OPEN; 60 | } 61 | } 62 | 63 | int userfs_read(GFILE *f, void * buf, int size){ 64 | if(f->obj){ 65 | return fread(buf, 1, size, f->obj); 66 | } 67 | return 0; 68 | } 69 | 70 | int userfs_write(GFILE *f, const void *buf, int size){ 71 | if(f->obj){ 72 | return fwrite(buf, 1, size, f->obj); 73 | } 74 | return 0; 75 | } 76 | 77 | bool_t userfs_setpos(GFILE *f, long int pos){ 78 | if(f->obj){ 79 | return fseek(f->obj, pos, SEEK_SET) != -1; 80 | } 81 | return 0; 82 | } 83 | 84 | long int userfs_getsize(GFILE * f){ 85 | if(f->obj){ 86 | long int oldpos = ftell(f->obj); 87 | fseek(f->obj, 0, SEEK_END); 88 | long int size = ftell(f->obj); 89 | fseek(f->obj, oldpos, SEEK_SET); 90 | return size; 91 | } 92 | return 0; 93 | } 94 | 95 | bool_t userfs_eof(GFILE *f){ 96 | if(f->obj){ 97 | return feof(f->obj); 98 | } 99 | return 0; 100 | } 101 | 102 | bool_t userfs_mount(const char* drive){ 103 | return 1; 104 | } 105 | 106 | bool_t userfs_unmount(const char* drive){ 107 | return 1; 108 | } 109 | 110 | bool_t userfs_sync(GFILE * f){ 111 | return 1; 112 | } 113 | -------------------------------------------------------------------------------- /components/ugfx-glue/gfx_userfs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "gfxconf.h" 7 | #include "gfx.h" 8 | #include 9 | #include 10 | 11 | #ifndef __GFX_USERFS 12 | #define __GFX_USERFS 13 | 14 | bool_t userfs_del(const char * fname); 15 | bool_t userfs_exists(const char * fname); 16 | long int userfs_filesize(const char * fname); 17 | bool_t userfs_ren(const char * oldname, const char * newname); 18 | bool_t userfs_open(GFILE *f, const char * fname); 19 | void userfs_close(GFILE *f); 20 | int userfs_read(GFILE *f, void * buf, int size); 21 | int userfs_write(GFILE *f, const void *buf, int size); 22 | bool_t userfs_setpos(GFILE *f, long int pos); 23 | long int userfs_getsize(GFILE * f); 24 | bool_t userfs_eof(GFILE *f); 25 | bool_t userfs_mount(const char* drive); 26 | bool_t userfs_unmount(const char* drive); 27 | bool_t userfs_sync(GFILE * f); 28 | 29 | const GFILEVMT FsUSERVMT = { 30 | .flags = GFSFLG_WRITEABLE|GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE, 31 | .prefix = 0, 32 | .del = &userfs_del, 33 | .exists = &userfs_exists, 34 | .filesize = &userfs_filesize, 35 | .ren = &userfs_ren, 36 | .open = &userfs_open, 37 | .close = &userfs_close, 38 | .read = &userfs_read, 39 | .write = &userfs_write, 40 | .setpos = &userfs_setpos, 41 | .getsize = &userfs_getsize, 42 | .eof = &userfs_eof, 43 | .mount = &userfs_mount, 44 | .unmount = &userfs_unmount, 45 | .sync = &userfs_sync, 46 | #if GFILE_NEED_FILELISTS 47 | #error "GFILE_NEED_FILELISTS Not implemented" 48 | .flopen = 0, 49 | .flread = 0, 50 | .flclose = 0, 51 | #endif 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /components/ugfx-glue/ginput_lld_toggle.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is subject to the terms of the GFX License. If a copy of 3 | * the license was not distributed with this file, you can obtain one at: 4 | * 5 | * http://ugfx.org/license.html 6 | */ 7 | 8 | #include 9 | 10 | #include "gfx.h" 11 | 12 | #if (GFX_USE_GINPUT && GINPUT_NEED_TOGGLE) 13 | #include "../../../src/ginput/ginput_driver_toggle.h" 14 | 15 | #include 16 | 17 | #include "ginput_lld_toggle_config.h" 18 | 19 | GINPUT_TOGGLE_DECLARE_STRUCTURE(); 20 | 21 | void 22 | ginput_lld_toggle_init(const GToggleConfig *ptc) 23 | { 24 | #ifdef CONFIG_SHA_BADGE_UGFX_GINPUT_DEBUG 25 | ets_printf("ginput_lld_toggle: init()\n"); 26 | #endif // CONFIG_SHA_BADGE_UGFX_GINPUT_DEBUG 27 | 28 | badge_input_notify = ginputToggleWakeupI; 29 | } 30 | 31 | unsigned 32 | ginput_lld_toggle_getbits(const GToggleConfig *ptc) 33 | { 34 | #ifdef CONFIG_SHA_BADGE_UGFX_GINPUT_DEBUG 35 | ets_printf("ginput_lld_toggle: getbits()\n"); 36 | #endif // CONFIG_SHA_BADGE_UGFX_GINPUT_DEBUG 37 | 38 | // drain input queue 39 | while (badge_input_get_event(0) != 0); 40 | 41 | // pass on button state 42 | return badge_input_button_state; 43 | } 44 | 45 | #endif /* GFX_USE_GINPUT && GINPUT_NEED_TOGGLE */ 46 | -------------------------------------------------------------------------------- /components/ugfx-glue/ginput_lld_toggle_config.h: -------------------------------------------------------------------------------- 1 | #ifndef GINPUT_LLD_TOGGLE_CONFIG 2 | #define GINPUT_LLD_TOGGLE_CONFIG 3 | 4 | // re-export BADGE_BUTTON_* constants 5 | #include 6 | 7 | #define GINPUT_TOGGLE_NUM_PORTS 32 8 | #define GINPUT_TOGGLE_CONFIG_ENTRIES 1 9 | 10 | // We are (well, will be) interrupt driven 11 | #define GINPUT_TOGGLE_POLL_PERIOD TIME_INFINITE 12 | 13 | #define GINPUT_TOGGLE_DECLARE_STRUCTURE() \ 14 | const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES] = { \ 15 | { 0, 0xffffffff, 0, 0 }, \ 16 | } 17 | 18 | #endif // GINPUT_LLD_TOGGLE_CONFIG 19 | -------------------------------------------------------------------------------- /components/ugfx-glue/userfonts.h: -------------------------------------------------------------------------------- 1 | // This file is generated by SHA2017-badge/Firmware/ugfx/build_fonts.sh 2 | #include "fonts/PermanentMarker22.c" 3 | #include "fonts/PermanentMarker36.c" 4 | #include "fonts/Roboto-Black22.c" 5 | #include "fonts/Roboto-BlackItalic24.c" 6 | #include "fonts/Roboto-Regular12.c" 7 | #include "fonts/Roboto-Regular18.c" 8 | #include "fonts/Roboto-Regular22.c" 9 | #include "fonts/DejaVuSans20.c" 10 | #include "fonts/weather42.c" 11 | #include "fonts/pixelade13.c" 12 | -------------------------------------------------------------------------------- /main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "Connectivity" 2 | 3 | config WIFI_USE 4 | bool "Use WiFi on badge" 5 | default y 6 | help 7 | Let the badge use wifi 8 | 9 | config WIFI_SSID 10 | string "WiFi SSID" 11 | depends on WIFI_USE 12 | default "SHA2017-badge" 13 | help 14 | SSID (network name) for the example to connect to. 15 | 16 | config WIFI_PASSWORD 17 | string "WiFi Password" 18 | depends on WIFI_USE 19 | default "b4dg3r" 20 | help 21 | WiFi password (WPA or WPA2) for the example to use. 22 | 23 | Can be left blank if the network has no security set. 24 | 25 | endmenu 26 | 27 | -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Main component makefile. 3 | # 4 | # This Makefile can be left empty. By default, it will take the sources in the 5 | # src/ directory, compile them and link them into lib(subdirectory_name).a 6 | # in the build directory. This behaviour is entirely configurable, 7 | # please read the ESP-IDF documents if you need to do this. 8 | # 9 | 10 | COMPONENT_EXTRA_INCLUDES := \ 11 | $(UGFX_PATH) \ 12 | $(UGFX_PATH)/src \ 13 | $(UGFX_PATH)/drivers/gdisp/framebuffer \ 14 | $(IDF_PATH)/components/freertos/include/freertos \ 15 | 16 | -------------------------------------------------------------------------------- /main/demo_dot1.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | void demoDot1(void) { 12 | uint32_t *tmpbuf = (uint32_t *) badge_eink_fb; 13 | 14 | /* clear screen */ 15 | memset(tmpbuf, 0xff, DISP_SIZE_X_B * DISP_SIZE_Y); 16 | 17 | struct badge_eink_update eink_upd = { 18 | .lut = BADGE_EINK_LUT_DEFAULT, 19 | .reg_0x3a = 26, // 26 dummy lines per gate 20 | .reg_0x3b = 0x08, // 62us per line 21 | .y_start = 0, 22 | .y_end = 295, 23 | }; 24 | badge_eink_update(tmpbuf, &eink_upd); 25 | 26 | // init LUT 27 | struct badge_eink_lut_entry lut[] = { 28 | { .length = 1, .voltages = 0x99, }, 29 | { .length = 0 } 30 | }; 31 | 32 | int px = 100; 33 | int py = 64; 34 | int xd = 1; 35 | int yd = 1; 36 | 37 | uint16_t dots[16] = { 38 | 0, 39 | }; 40 | int dot_pos = 0; 41 | 42 | while (1) { 43 | if (badge_input_get_event(10) != 0) 44 | return; 45 | 46 | /* update dot */ 47 | if (px + xd < 0) 48 | xd = -xd; 49 | if (px + xd >= DISP_SIZE_X) 50 | xd = -xd; 51 | px += xd; 52 | 53 | if (py + yd < 0) 54 | yd = -yd; 55 | if (py + yd >= DISP_SIZE_Y) 56 | yd = -yd; 57 | py += yd; 58 | 59 | dots[dot_pos] = (py << 7) | px; 60 | dot_pos++; 61 | if (dot_pos == 16) 62 | dot_pos = 0; 63 | 64 | /* clear screen */ 65 | memset(tmpbuf, 0xff, DISP_SIZE_X_B * DISP_SIZE_Y); 66 | 67 | int i; 68 | for (i = 0; i < 16; i++) { 69 | int px = dots[i] & 127; 70 | int py = dots[i] >> 7; 71 | tmpbuf[(px >> 5) + py*4] &= ~( 0x80000000 >> (px & 31) ); 72 | } 73 | 74 | struct badge_eink_update eink_upd = { 75 | .lut = BADGE_EINK_LUT_CUSTOM, 76 | .lut_custom = lut, 77 | .reg_0x3a = 2, // 2 dummy lines per gate 78 | .reg_0x3b = 0, // 30us per line 79 | .y_start = 0, 80 | .y_end = 295, 81 | }; 82 | badge_eink_update(tmpbuf, &eink_upd); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /main/demo_dot1.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_DOT1_H 2 | #define DEMO_DOT1_H 3 | 4 | extern void demoDot1(void); 5 | 6 | #endif // DEMO_DOT1_H 7 | -------------------------------------------------------------------------------- /main/demo_greyscale1.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | void demoGreyscale1(void) { 13 | uint32_t *tmpbuf = (uint32_t *) badge_eink_fb; 14 | 15 | int i; 16 | for (i = 0; i < 2; i++) { 17 | /* draw test pattern */ 18 | { 19 | uint32_t *dptr = tmpbuf; 20 | int x, y; 21 | for (y = 0; y < DISP_SIZE_Y; y++) { 22 | for (x = 0; x < 4; x++) 23 | *dptr++ = (x & 1) ? 0xffffffff : 0x00000000; 24 | } 25 | } 26 | 27 | struct badge_eink_update eink_upd = { 28 | .lut = BADGE_EINK_LUT_DEFAULT, 29 | .reg_0x3a = 26, // 26 dummy lines per gate 30 | .reg_0x3b = 0x08, // 62us per line 31 | .y_start = 0, 32 | .y_end = 295, 33 | }; 34 | badge_eink_update(tmpbuf, &eink_upd); 35 | } 36 | 37 | int y = 0; 38 | int n = 8; 39 | while (y < DISP_SIZE_Y) { 40 | /* draw new test pattern */ 41 | { 42 | uint32_t *dptr = tmpbuf; 43 | int x, y; 44 | for (y = 0; y < DISP_SIZE_Y; y++) { 45 | for (x = 0; x < 4; x++) 46 | *dptr++ = 0xffff0000; 47 | } 48 | } 49 | 50 | if (y + n > DISP_SIZE_Y) 51 | n = DISP_SIZE_Y - y; 52 | 53 | struct badge_eink_update eink_upd = { 54 | .lut = BADGE_EINK_LUT_DEFAULT, 55 | .reg_0x3a = 26, // 26 dummy lines per gate 56 | .reg_0x3b = 0x08, // 62us per line 57 | .y_start = y, 58 | .y_end = y+n, 59 | }; 60 | badge_eink_update(tmpbuf, &eink_upd); 61 | 62 | vTaskDelay(1000 / portTICK_PERIOD_MS); 63 | y += n; 64 | n += 4; 65 | } 66 | y = 0; 67 | n = 4; 68 | while (y < DISP_SIZE_Y) { 69 | /* draw new test pattern */ 70 | { 71 | uint32_t *dptr = tmpbuf; 72 | int x, y; 73 | for (y = 0; y < DISP_SIZE_Y; y++) { 74 | for (x = 0; x < 4; x++) 75 | *dptr++ = (x & 2) ? 0xffffffff : 0x00000000; 76 | } 77 | } 78 | 79 | if (y + n > DISP_SIZE_Y) 80 | n = DISP_SIZE_Y - y; 81 | 82 | struct badge_eink_update eink_upd = { 83 | .lut = BADGE_EINK_LUT_DEFAULT, 84 | .reg_0x3a = 26, // 26 dummy lines per gate 85 | .reg_0x3b = 0x08, // 62us per line 86 | .y_start = y, 87 | .y_end = y+n, 88 | }; 89 | badge_eink_update(tmpbuf, &eink_upd); 90 | 91 | vTaskDelay(1000 / portTICK_PERIOD_MS); 92 | y += n; 93 | n += 2; 94 | } 95 | 96 | // wait for random keypress 97 | badge_input_get_event(-1); 98 | } 99 | -------------------------------------------------------------------------------- /main/demo_greyscale1.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_GREYSCALE1_H 2 | #define DEMO_GREYSCALE1_H 3 | 4 | extern void demoGreyscale1(void); 5 | 6 | #endif // DEMO_GREYSCALE1_H 7 | -------------------------------------------------------------------------------- /main/demo_greyscale2.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void demoGreyscale2(void) { 10 | uint32_t *tmpbuf = (uint32_t *) badge_eink_fb; 11 | 12 | int i; 13 | for (i = 0; i < 3; i++) { 14 | /* draw initial pattern */ 15 | { 16 | uint32_t *dptr = tmpbuf; 17 | int y; 18 | for (y = 0; y < DISP_SIZE_Y; y++) { 19 | *dptr++ = (i & 1) ? 0xffffffff : 0x00000000; 20 | *dptr++ = (i & 1) ? 0xffffffff : 0x00000000; 21 | *dptr++ = (i & 1) ? 0x00000000 : 0xffffffff; 22 | *dptr++ = (i & 1) ? 0x00000000 : 0xffffffff; 23 | } 24 | } 25 | 26 | struct badge_eink_update eink_upd = { 27 | .lut = BADGE_EINK_LUT_DEFAULT, 28 | .reg_0x3a = 26, // 26 dummy lines per gate 29 | .reg_0x3b = 0x08, // 62us per line 30 | .y_start = 0, 31 | .y_end = 295, 32 | }; 33 | badge_eink_update(tmpbuf, &eink_upd); 34 | } 35 | 36 | 37 | for (i = 1; i < 16; i++) { 38 | /* draw pattern */ 39 | int y_first = 19; 40 | int y_next = (i + 1) * 19; 41 | if (y_next > DISP_SIZE_Y) 42 | y_next = DISP_SIZE_Y; 43 | 44 | uint32_t *dptr = tmpbuf; 45 | int y; 46 | for (y = 0; y < y_first; y++) { 47 | *dptr++ = 0x00000000; 48 | *dptr++ = 0x00000000; 49 | *dptr++ = 0xffffffff; 50 | *dptr++ = 0xffffffff; 51 | } 52 | for (y = y_first; y < y_next; y++) { 53 | *dptr++ = 0xffffffff; 54 | *dptr++ = 0xffffffff; 55 | *dptr++ = 0x00000000; 56 | *dptr++ = 0x00000000; 57 | } 58 | for (y = y_next; y < DISP_SIZE_Y; y++) { 59 | *dptr++ = 0x00000000; 60 | *dptr++ = 0x00000000; 61 | *dptr++ = 0xffffffff; 62 | *dptr++ = 0xffffffff; 63 | } 64 | 65 | /* update LUT */ 66 | struct badge_eink_lut_entry lut[] = { 67 | { .length = i, .voltages = 0x18, }, 68 | { .length = 0 } 69 | }; 70 | 71 | struct badge_eink_update eink_upd = { 72 | .lut = BADGE_EINK_LUT_CUSTOM, 73 | .lut_custom = lut, 74 | .reg_0x3a = 2, // 2 dummy lines per gate 75 | .reg_0x3b = 0x00, // 30us per line 76 | .y_start = 0, 77 | .y_end = 295, 78 | }; 79 | badge_eink_update(tmpbuf, &eink_upd); 80 | } 81 | 82 | // wait for random keypress 83 | badge_input_get_event(-1); 84 | } 85 | -------------------------------------------------------------------------------- /main/demo_greyscale2.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_GREYSCALE2_H 2 | #define DEMO_GREYSCALE2_H 3 | 4 | extern void demoGreyscale2(void); 5 | 6 | #endif // DEMO_GREYSCALE2_H 7 | -------------------------------------------------------------------------------- /main/demo_greyscale_img1.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "img_hacking.h" 12 | 13 | /* 14 | * The greyscale curve was generated with: 15 | * 16 | * perl -MPOSIX -we 'my $e = 0.15; my $n=15; for (my $i=0; $i<=$n; $i++) { print 17 | * (POSIX::round(255 / (1-$e) - ($e**($i/$n)) * 255 / (1-$e)),"\n") }' | xargs | 18 | * sed 's/ /,/g' 19 | */ 20 | void demoGreyscaleImg1(void) { 21 | uint32_t *tmpbuf = (uint32_t *) badge_eink_fb; 22 | 23 | // trying to get rid of all ghosting and end with a black screen. 24 | int i; 25 | for (i = 0; i < 3; i++) { 26 | /* draw initial pattern */ 27 | memset(tmpbuf, (i & 1) ? 0xff : 0x00, DISP_SIZE_X_B * DISP_SIZE_Y); 28 | 29 | struct badge_eink_update eink_upd = { 30 | .lut = BADGE_EINK_LUT_DEFAULT, 31 | .reg_0x3a = 26, // 26 dummy lines per gate 32 | .reg_0x3b = 0x08, // 62us per line 33 | .y_start = 0, 34 | .y_end = 295, 35 | }; 36 | badge_eink_update(tmpbuf, &eink_upd); 37 | } 38 | 39 | for (i = 0; i < 16; i++) { 40 | // curved 41 | const uint8_t lvl_buf[16] = { 42 | // 0,32,61,87,110,131,150,167,182,196,209,220,230,239,248,255 43 | //// 0.21 44 | 0, 36, 67, 95, 119, 141, 160, 176, 45 | 191, 204, 215, 225, 234, 242, 249, 255 // 0.15 46 | }; 47 | uint8_t lvl = lvl_buf[i]; 48 | int x, y; 49 | const uint8_t *ptr = img_hacking; 50 | uint32_t *dptr = tmpbuf; 51 | for (y = 0; y < DISP_SIZE_Y; y++) { 52 | uint32_t res = 0; 53 | for (x = 0; x < DISP_SIZE_X; x++) { 54 | res <<= 1; 55 | if (*ptr++ <= lvl) 56 | res++; 57 | if ((x & 31) == 31) 58 | *dptr++ = res; 59 | } 60 | } 61 | 62 | /* update LUT */ 63 | struct badge_eink_lut_entry lut[] = { 64 | { .length = i, .voltages = 0x18, }, 65 | { .length = 0 } 66 | }; 67 | 68 | struct badge_eink_update eink_upd = { 69 | .lut = BADGE_EINK_LUT_CUSTOM, 70 | .lut_custom = lut, 71 | .reg_0x3a = 0, // no dummy lines per gate 72 | .reg_0x3b = 0, // 30us per line 73 | .y_start = 0, 74 | .y_end = 295, 75 | }; 76 | badge_eink_update(tmpbuf, &eink_upd); 77 | } 78 | 79 | // wait for random keypress 80 | badge_input_get_event(-1); 81 | } 82 | -------------------------------------------------------------------------------- /main/demo_greyscale_img1.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_GREYSCALE_IMG1_H 2 | #define DEMO_GREYSCALE_IMG1_H 3 | 4 | extern void demoGreyscaleImg1(void); 5 | 6 | #endif // DEMO_GREYSCALE_IMG1_H 7 | -------------------------------------------------------------------------------- /main/demo_greyscale_img2.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "img_hacking.h" 12 | 13 | void demoGreyscaleImg2(void) { 14 | uint32_t *tmpbuf = (uint32_t *) badge_eink_fb; 15 | 16 | // curved 17 | const uint8_t lvl_buf[64] = { 18 | 0, 9, 18, 26, 34, 42, 50, 57, 64, 71, 78, 85, 91, 19 | 97, 103, 109, 115, 120, 126, 131, 136, 141, 145, 150, 154, 159, 20 | 163, 167, 171, 175, 178, 182, 186, 189, 192, 195, 199, 202, 204, 21 | 207, 210, 213, 215, 218, 220, 223, 225, 227, 229, 231, 233, 235, 22 | 237, 239, 241, 243, 244, 246, 248, 249, 251, 252, 254, 255 // e=0.15, n=63 23 | }; 24 | 25 | // trying to get rid of all ghosting and end with a black screen. 26 | int i; 27 | for (i = 0; i < 3; i++) { 28 | /* draw initial pattern */ 29 | memset(tmpbuf, (i & 1) ? 0xff : 0x00, DISP_SIZE_X_B * DISP_SIZE_Y); 30 | 31 | struct badge_eink_update eink_upd = { 32 | .lut = BADGE_EINK_LUT_DEFAULT, 33 | .reg_0x3a = 26, // 26 dummy lines per gate 34 | .reg_0x3b = 0x08, // 62us per line 35 | .y_start = 0, 36 | .y_end = 295, 37 | }; 38 | badge_eink_update(tmpbuf, &eink_upd); 39 | } 40 | 41 | int j; 42 | for (j = 0; j < 4; j++) { 43 | int y_start = 0 + j * (DISP_SIZE_Y / 4); 44 | int y_end = y_start + (DISP_SIZE_Y / 4) - 1; 45 | 46 | for (i = 32; i > 0; i >>= 1) { 47 | int x, y; 48 | const uint8_t *ptr = img_hacking; 49 | uint32_t *dptr = tmpbuf; 50 | for (y = 0; y < DISP_SIZE_Y; y++) { 51 | uint32_t res = 0; 52 | for (x = 0; x < DISP_SIZE_X; x++) { 53 | res <<= 1; 54 | uint8_t pixel = *ptr++; 55 | int j; 56 | for (j = 0; pixel > lvl_buf[j]; j++) 57 | ; 58 | if (y >= y_start && y <= y_end && j & i) 59 | res++; 60 | if ((x & 31) == 31) 61 | *dptr++ = res; 62 | } 63 | } 64 | 65 | // LUT: 66 | // Ignore old state; 67 | // Do nothing when bit is not set; 68 | // Make pixel whiter when bit is set; 69 | // Duration is cycles. 70 | struct badge_eink_lut_entry lut[] = { 71 | { .length = i, .voltages = 0x88, }, 72 | { .length = 0 } 73 | }; 74 | 75 | struct badge_eink_update eink_upd = { 76 | .lut = BADGE_EINK_LUT_CUSTOM, 77 | .lut_custom = lut, 78 | .reg_0x3a = 0, // no dummy lines per gate 79 | .reg_0x3b = 0, // 30us per line 80 | .y_start = y_start, 81 | .y_end = y_end + 1, 82 | }; 83 | badge_eink_update(tmpbuf, &eink_upd); 84 | } 85 | } 86 | 87 | // wait for random keypress 88 | badge_input_get_event(-1); 89 | } 90 | -------------------------------------------------------------------------------- /main/demo_greyscale_img2.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_GREYSCALE_IMG2_H 2 | #define DEMO_GREYSCALE_IMG2_H 3 | 4 | extern void demoGreyscaleImg2(void); 5 | 6 | #endif // DEMO_GREYSCALE_IMG2_H 7 | -------------------------------------------------------------------------------- /main/demo_greyscale_img3.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "img_hacking.h" 12 | 13 | void demoGreyscaleImg3(void) { 14 | uint32_t *tmpbuf = (uint32_t *) badge_eink_fb; 15 | 16 | // curved 17 | const uint8_t lvl_buf[128] = { 18 | 0, 4, 9, 13, 17, 22, 26, 30, 34, 38, 42, 45, 49, 53, 57, 19 | 60, 64, 67, 71, 74, 77, 81, 84, 87, 90, 93, 97, 100, 103, 105, 20 | 108, 111, 114, 117, 119, 122, 125, 127, 130, 132, 135, 137, 140, 142, 145, 21 | 147, 149, 151, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 22 | 178, 179, 181, 183, 185, 186, 188, 190, 191, 193, 195, 196, 198, 199, 201, 23 | 202, 204, 205, 206, 208, 209, 211, 212, 213, 214, 216, 217, 218, 219, 221, 24 | 222, 223, 224, 225, 226, 227, 228, 230, 231, 232, 233, 234, 235, 236, 237, 25 | 237, 238, 239, 240, 241, 242, 243, 244, 245, 245, 246, 247, 248, 249, 249, 26 | 250, 251, 252, 252, 253, 254, 254, 255 // e=0.15, n=127 27 | }; 28 | 29 | // trying to get rid of all ghosting and end with a black screen. 30 | int i; 31 | for (i = 0; i < 3; i++) { 32 | /* draw initial pattern */ 33 | memset(tmpbuf, (i & 1) ? 0xff : 0x00, DISP_SIZE_X_B * DISP_SIZE_Y); 34 | 35 | struct badge_eink_update eink_upd = { 36 | .lut = BADGE_EINK_LUT_DEFAULT, 37 | .reg_0x3a = 26, // 26 dummy lines per gate 38 | .reg_0x3b = 0x08, // 62us per line 39 | .y_start = 0, 40 | .y_end = 295, 41 | }; 42 | badge_eink_update(tmpbuf, &eink_upd); 43 | } 44 | 45 | for (i = 64; i > 0; i >>= 1) { 46 | int ii = i; 47 | int p = 8; 48 | 49 | while ((ii & 1) == 0 && (p > 1)) { 50 | ii >>= 1; 51 | p >>= 1; 52 | } 53 | 54 | int j; 55 | for (j = 0; j < p; j++) { 56 | int y_start = 0 + j * (DISP_SIZE_Y / p); 57 | int y_end = y_start + (DISP_SIZE_Y / p) - 1; 58 | 59 | int x, y; 60 | const uint8_t *ptr = img_hacking; 61 | uint32_t *dptr = tmpbuf; 62 | for (y = 0; y < DISP_SIZE_Y; y++) { 63 | uint32_t res = 0; 64 | for (x = 0; x < DISP_SIZE_X; x++) { 65 | res <<= 1; 66 | uint8_t pixel = *ptr++; 67 | int j; 68 | for (j = 0; pixel > lvl_buf[j]; j++) 69 | ; 70 | if (y >= y_start && y <= y_end && j & i) 71 | res++; 72 | if ((x & 31) == 31) 73 | *dptr++ = res; 74 | } 75 | } 76 | 77 | // LUT: 78 | // Ignore old state; 79 | // Do nothing when bit is not set; 80 | // Make pixel whiter when bit is set; 81 | // Duration is cycles. 82 | struct badge_eink_lut_entry lut[] = { 83 | { .length = ii, .voltages = 0x88, }, 84 | { .length = 0 } 85 | }; 86 | 87 | struct badge_eink_update eink_upd = { 88 | .lut = BADGE_EINK_LUT_CUSTOM, 89 | .lut_custom = lut, 90 | .reg_0x3a = 0, // no dummy lines per gate 91 | .reg_0x3b = 0, // 30us per line 92 | .y_start = y_start, 93 | .y_end = y_end + 1, 94 | }; 95 | badge_eink_update(tmpbuf, &eink_upd); 96 | } 97 | } 98 | 99 | // wait for random keypress 100 | badge_input_get_event(-1); 101 | } 102 | -------------------------------------------------------------------------------- /main/demo_greyscale_img3.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_GREYSCALE_IMG3_H 2 | #define DEMO_GREYSCALE_IMG3_H 3 | 4 | extern void demoGreyscaleImg3(void); 5 | 6 | #endif // DEMO_GREYSCALE_IMG3_H 7 | -------------------------------------------------------------------------------- /main/demo_greyscale_img4.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "imgv2_hacking.h" 7 | 8 | void 9 | demoGreyscaleImg4(void) 10 | { 11 | badge_eink_display_greyscale(imgv2_hacking, DISPLAY_FLAG_8BITPIXEL, BADGE_EINK_MAX_LAYERS); 12 | 13 | // wait for random keypress 14 | badge_input_get_event(-1); 15 | } 16 | -------------------------------------------------------------------------------- /main/demo_greyscale_img4.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_GREYSCALE_IMG4_H 2 | #define DEMO_GREYSCALE_IMG4_H 3 | 4 | extern void demoGreyscaleImg4(void); 5 | 6 | #endif // DEMO_GREYSCALE_IMG4_H 7 | -------------------------------------------------------------------------------- /main/demo_leds.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #ifdef PIN_NUM_LEDS 14 | 15 | #if 0 16 | #define L0 0 17 | #define L1 21 18 | #define L2 42 19 | #define L3 63 20 | #else 21 | #define L0 0 22 | #define L1 10 23 | #define L2 20 24 | #define L3 30 25 | #endif 26 | 27 | void 28 | demo_leds(void) 29 | { 30 | esp_err_t err = badge_eink_fb_init(); 31 | assert( err == ESP_OK ); 32 | 33 | memset(badge_eink_fb, 0xff, BADGE_EINK_FB_LEN); 34 | draw_font(badge_eink_fb, 6, 16, 284, "testing leds. colors should be:", 35 | FONT_INVERT); 36 | draw_font(badge_eink_fb, 6, 26, 284, ",,,,,", 37 | FONT_INVERT); 38 | badge_eink_display(badge_eink_fb, DISPLAY_FLAG_LUT(2)); 39 | 40 | { 41 | uint8_t grbw[6*4] = { 42 | 0, 0, 0, 0, 43 | 0, 0, 0, 10, 44 | 0, 0, 0, 40, 45 | 0, 0, 40, 0, 46 | 40, 0, 0, 0, 47 | 0, 40, 0, 0, 48 | }; // show R, G, B, W 49 | badge_leds_send_data(grbw, sizeof(grbw)); 50 | if (badge_input_get_event(10000) != 0) 51 | { 52 | badge_leds_disable(); 53 | return; 54 | } 55 | } 56 | 57 | memset(badge_eink_fb, 0xff, BADGE_EINK_FB_LEN); 58 | draw_font(badge_eink_fb, 6, 16, 264, "now doing random updates", 59 | FONT_INVERT); 60 | badge_eink_display(badge_eink_fb, DISPLAY_FLAG_LUT(2)); 61 | 62 | uint8_t grbw[6*4] = { 63 | L0, L1, L2, L3, 64 | L1, L0, L1, L2, 65 | L2, L1, L0, L1, 66 | L3, L2, L1, L0, 67 | L2, L3, L2, L1, 68 | L1, L2, L3, L2, 69 | }; 70 | 71 | int8_t dir[6*4] = { 72 | +1, +1, +1, -1, 73 | -1, +1, +1, +1, 74 | -1, -1, +1, +1, 75 | -1, -1, -1, +1, 76 | +1, -1, -1, -1, 77 | +1, +1, -1, -1, 78 | }; 79 | 80 | while (1) { 81 | // exit on random keypress 82 | if (badge_input_get_event(10) != 0) 83 | break; 84 | 85 | badge_leds_send_data(grbw, sizeof(grbw)); 86 | 87 | int i; 88 | for (i=0; i<6*4; i++) { 89 | grbw[i] += dir[i]; 90 | if (grbw[i] == L0) 91 | dir[i] = +1; 92 | if (grbw[i] == L3) 93 | dir[i] = -1; 94 | } 95 | } 96 | 97 | memset(badge_eink_fb, 0xff, BADGE_EINK_FB_LEN); 98 | draw_font(badge_eink_fb, 6, 16, 264, "key pressed. disabling leds", 99 | FONT_INVERT); 100 | badge_eink_display(badge_eink_fb, DISPLAY_FLAG_LUT(2)); 101 | 102 | badge_leds_disable(); 103 | 104 | memset(badge_eink_fb, 0xff, BADGE_EINK_FB_LEN); 105 | draw_font(badge_eink_fb, 6, 16, 264, "leds are disabled.", 106 | FONT_INVERT); 107 | badge_eink_display(badge_eink_fb, DISPLAY_FLAG_LUT(2)); 108 | } 109 | #endif // PIN_NUM_LEDS 110 | -------------------------------------------------------------------------------- /main/demo_leds.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_LEDS_H 2 | #define DEMO_LEDS_H 3 | 4 | extern void demo_leds(void); 5 | 6 | #endif // DEMO_LEDS_H 7 | -------------------------------------------------------------------------------- /main/demo_mpr121.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | #ifdef I2C_MPR121_ADDR 5 | #include 6 | 7 | #include 8 | #include "freertos/FreeRTOS.h" 9 | #include "freertos/semphr.h" 10 | #include "freertos/task.h" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | #include "demo_mpr121.h" 21 | 22 | void 23 | demoMpr121(void) 24 | { 25 | static const char *names[8] = { 26 | "A", 27 | "B", 28 | "Start", 29 | "Select", 30 | "Down", 31 | "Right", 32 | "Up", 33 | "Left", 34 | }; 35 | 36 | esp_err_t err = badge_eink_fb_init(); 37 | assert( err == ESP_OK ); 38 | 39 | while (1) 40 | { 41 | memset(badge_eink_fb, 0xff, BADGE_EINK_FB_LEN); 42 | struct badge_mpr121_touch_info info; 43 | 44 | int res = badge_mpr121_get_touch_info(&info); 45 | 46 | int i; 47 | for (i=0; i<8; i++) 48 | { 49 | int flags = 0; 50 | if ((info.touch_state >> i) & 1) 51 | flags |= FONT_INVERT; 52 | 53 | draw_font(badge_eink_fb, 2, 16 + 10*i, 36, names[i], (FONT_FULL_WIDTH | FONT_INVERT) ^ flags); 54 | if (res == ESP_OK) { 55 | int x, y; 56 | int d = (info.data[i] >> 2) & 255; 57 | for (y=18+10*i; y<20+10*i; y++) 58 | { 59 | for (x=40; x<40+d; x++) 60 | { 61 | badge_eink_fb[y*(296/8) + (x/8)] &= ~( 1 << (x&7) ); 62 | } 63 | } 64 | d = info.baseline[i] & 255; 65 | for (y=20+10*i; y<22+10*i; y++) 66 | { 67 | for (x=40; x<40+d; x++) 68 | { 69 | badge_eink_fb[y*(296/8) + (x/8)] &= ~( 1 << (x&7) ); 70 | } 71 | } 72 | d = info.baseline[i] - (info.touch[i] >> 2); 73 | if (d < 0) d = 0; 74 | d &= 255; 75 | for (y=22+10*i; y<24+10*i; y++) 76 | { 77 | for (x=40+d-1; x<40+d+1; x++) 78 | { 79 | badge_eink_fb[y*(296/8) + (x/8)] &= ~( 1 << (x&7) ); 80 | } 81 | } 82 | d = info.baseline[i] - (info.release[i] >> 2); 83 | if (d < 0) d = 0; 84 | d &= 255; 85 | for (y=16+10*i; y<18+10*i; y++) 86 | { 87 | for (x=40+d-1; x<40+d+1; x++) 88 | { 89 | badge_eink_fb[y*(296/8) + (x/8)] &= ~( 1 << (x&7) ); 90 | } 91 | } 92 | } 93 | } 94 | 95 | /* update display */ 96 | badge_eink_display(badge_eink_fb, DISPLAY_FLAG_LUT(2)); 97 | 98 | // wait 0.1 second 99 | badge_input_get_event(100); 100 | } 101 | } 102 | 103 | #endif // I2C_MPR121_ADDR 104 | -------------------------------------------------------------------------------- /main/demo_mpr121.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_MPR121_H 2 | #define DEMO_MPR121_H 3 | 4 | #include "sdkconfig.h" 5 | 6 | #include 7 | #ifdef I2C_MPR121_ADDR 8 | extern void demoMpr121(void); 9 | #endif // I2C_MPR121_ADDR 10 | 11 | #endif // DEMO_MPR121_H 12 | -------------------------------------------------------------------------------- /main/demo_partial_update.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "imgv2_sha.h" 9 | #include "imgv2_nick.h" 10 | 11 | void 12 | demoPartialUpdate(void) { 13 | struct badge_eink_update eink_upd = { 14 | .lut = BADGE_EINK_LUT_DEFAULT, 15 | // .reg_0x3a = 26, // 26 dummy lines per gate 16 | .reg_0x3a = 63, // 63 dummy lines per gate 17 | // .reg_0x3b = 0x08, // 62us per line 18 | .reg_0x3b = 0x0f, // 208us per line 19 | .y_start = 0, 20 | .y_end = 295, 21 | }; 22 | 23 | int i; 24 | for (i = 0; i < 8; i++) { 25 | int j = ((i << 1) | (i >> 2)) & 7; 26 | badge_eink_display(imgv2_sha, DISPLAY_FLAG_NO_UPDATE); 27 | eink_upd.y_start = 37 * j; 28 | eink_upd.y_end = 37 * j + 36; 29 | badge_eink_update(NULL, &eink_upd); 30 | 31 | vTaskDelay(1000 / portTICK_PERIOD_MS); 32 | } 33 | 34 | for (i = 0; i < 8; i++) { 35 | int j = ((i << 1) | (i >> 2)) & 7; 36 | badge_eink_display(imgv2_nick, DISPLAY_FLAG_NO_UPDATE); 37 | eink_upd.y_start = 37 * j; 38 | eink_upd.y_end = 37 * j + 36; 39 | badge_eink_update(NULL, &eink_upd); 40 | 41 | vTaskDelay(1000 / portTICK_PERIOD_MS); 42 | } 43 | 44 | // wait for random keypress 45 | badge_input_get_event(-1); 46 | } 47 | -------------------------------------------------------------------------------- /main/demo_partial_update.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_PARTIAL_UPDATE_H 2 | #define DEMO_PARTIAL_UPDATE_H 3 | 4 | #include "sdkconfig.h" 5 | 6 | extern void demoPartialUpdate(void); 7 | 8 | #endif // DEMO_PARTIAL_UPDATE_H 9 | -------------------------------------------------------------------------------- /main/demo_power.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | void 15 | demoPower(void) { 16 | char text[32]; 17 | 18 | bool bat_cs = false; 19 | int v_bat = -1; 20 | int v_usb = -1; 21 | 22 | esp_err_t err = badge_eink_fb_init(); 23 | assert( err == ESP_OK ); 24 | 25 | while (1) 26 | { 27 | #if defined(PORTEXP_PIN_NUM_CHRGSTAT) || defined(MPR121_PIN_NUM_CHRGSTAT) 28 | bool new_bat_cs = badge_battery_charge_status(); 29 | #else 30 | bool new_bat_cs = false; 31 | #endif 32 | #ifdef ADC1_CHAN_VBAT_SENSE 33 | int new_v_bat = badge_battery_volt_sense(); 34 | #else 35 | int new_v_bat = 0; 36 | #endif 37 | #ifdef ADC1_CHAN_VBAT_SENSE 38 | int new_v_usb = badge_usb_volt_sense(); 39 | #else 40 | int new_v_usb = 0; 41 | #endif 42 | 43 | if (bat_cs != new_bat_cs || 44 | v_bat != new_v_bat || v_usb != new_v_usb) 45 | { 46 | bat_cs = new_bat_cs; 47 | v_bat = new_v_bat; 48 | v_usb = new_v_usb; 49 | 50 | memset(badge_eink_fb, 0xff, BADGE_EINK_FB_LEN); 51 | 52 | snprintf(text, sizeof(text), "Is charging: %s", bat_cs ? "true" : "false"); 53 | draw_font(badge_eink_fb, 16, 8, BADGE_EINK_WIDTH-32, text, 54 | FONT_MONOSPACE | FONT_INVERT); 55 | 56 | snprintf(text, sizeof(text), "Vusb : %d.%03d V", v_usb / 1000, v_usb % 1000); 57 | draw_font(badge_eink_fb, 16, 16, BADGE_EINK_WIDTH-32, text, 58 | FONT_MONOSPACE | FONT_INVERT); 59 | 60 | snprintf(text, sizeof(text), "Vbat : %d.%03d V", v_bat / 1000, v_bat % 1000); 61 | draw_font(badge_eink_fb, 16, 24, BADGE_EINK_WIDTH-32, text, 62 | FONT_MONOSPACE | FONT_INVERT); 63 | 64 | /* update display */ 65 | badge_eink_display(badge_eink_fb, DISPLAY_FLAG_LUT(2)); 66 | } 67 | 68 | // wait 1 second 69 | if (badge_input_get_event(1000) != 0) 70 | return; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /main/demo_power.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_POWER_H 2 | #define DEMO_POWER_H 3 | 4 | #include "sdkconfig.h" 5 | 6 | extern void demoPower(void); 7 | 8 | #endif // DEMO_POWER_H 9 | -------------------------------------------------------------------------------- /main/demo_sdcard_image.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "esp_err.h" 9 | #include "esp_log.h" 10 | #include "esp_vfs_fat.h" 11 | #include "driver/sdmmc_host.h" 12 | #include "driver/sdmmc_defs.h" 13 | #include "sdmmc_cmd.h" 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | static const char* TAG = "example"; 24 | 25 | void 26 | demo_sdcard_image(void) 27 | { 28 | esp_err_t err = badge_eink_fb_init(); 29 | assert( err == ESP_OK ); 30 | 31 | memset(badge_eink_fb, 0, BADGE_EINK_FB_LEN); 32 | 33 | badge_power_sdcard_enable(); 34 | 35 | sdmmc_host_t host = SDMMC_HOST_DEFAULT(); 36 | host.flags = SDMMC_HOST_FLAG_1BIT; 37 | sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); 38 | 39 | esp_vfs_fat_sdmmc_mount_config_t mount_config = { 40 | .format_if_mount_failed = false, 41 | .max_files = 5 42 | }; 43 | 44 | sdmmc_card_t* card; 45 | esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card); 46 | if (ret != ESP_OK) { 47 | if (ret == ESP_FAIL) { 48 | ESP_LOGE(TAG, "Failed to mount filesystem. If you want the card to be formatted, set format_if_mount_failed = true."); 49 | } else { 50 | ESP_LOGE(TAG, "Failed to initialize the card (%d). Make sure SD card lines have pull-up resistors in place.", ret); 51 | } 52 | return; 53 | } 54 | 55 | // Card has been initialized, print its properties 56 | sdmmc_card_print_info(stdout, card); 57 | 58 | struct lib_file_reader *fr = lib_file_new("/sdcard/images/hacking-test.png", 1024); 59 | if (fr == NULL) 60 | { 61 | perror("open()"); 62 | esp_vfs_fat_sdmmc_unmount(); 63 | badge_power_sdcard_disable(); 64 | return; 65 | } 66 | 67 | struct lib_png_reader *pr = lib_png_new((lib_reader_read_t) &lib_file_read, fr); 68 | if (pr == NULL) 69 | { 70 | fprintf(stderr, "out of memory.\n"); 71 | lib_file_destroy(fr); 72 | esp_vfs_fat_sdmmc_unmount(); 73 | badge_power_sdcard_disable(); 74 | return; 75 | } 76 | 77 | int res = lib_png_load_image(pr, badge_eink_fb, 0, 0, BADGE_EINK_WIDTH, BADGE_EINK_HEIGHT, BADGE_EINK_WIDTH); 78 | lib_png_destroy(pr); 79 | lib_file_destroy(fr); 80 | esp_vfs_fat_sdmmc_unmount(); 81 | badge_power_sdcard_disable(); 82 | 83 | if (res < 0) 84 | { 85 | fprintf(stderr, "failed to load image: res = %i\n", res); 86 | return; 87 | } 88 | 89 | badge_eink_display_greyscale(badge_eink_fb, DISPLAY_FLAG_8BITPIXEL, BADGE_EINK_MAX_LAYERS); 90 | 91 | // wait for random keypress 92 | badge_input_get_event(-1); 93 | } 94 | -------------------------------------------------------------------------------- /main/demo_sdcard_image.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_SDCARD_IMAGE_H 2 | #define DEMO_SDCARD_IMAGE_H 3 | 4 | extern void demo_sdcard_image(void); 5 | 6 | #endif // DEMO_SDCARD_IMAGE_H 7 | -------------------------------------------------------------------------------- /main/demo_test_adc.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | void 15 | demoTestAdc(void) { 16 | int channel; 17 | int adc_mask = 0xff; 18 | 19 | esp_err_t err = badge_eink_fb_init(); 20 | assert( err == ESP_OK ); 21 | 22 | adc1_config_width(ADC_WIDTH_12Bit); 23 | for (channel = 0; channel < ADC1_CHANNEL_MAX; channel++) 24 | { 25 | if (adc_mask & (1 << channel)) 26 | { 27 | adc1_config_channel_atten(channel, ADC_ATTEN_0db); 28 | } 29 | } 30 | 31 | while (1) 32 | { 33 | memset(badge_eink_fb, 0xff, BADGE_EINK_FB_LEN); 34 | 35 | for (channel = 0; channel < ADC1_CHANNEL_MAX; channel++) 36 | { 37 | #define TEXTLEN 32 38 | char text[TEXTLEN]; 39 | int val; 40 | if (adc_mask & (1 << channel)) 41 | val = adc1_get_raw(channel); 42 | else 43 | val = -1; 44 | snprintf(text, TEXTLEN, "ADC channel %d: %d", channel, val); 45 | draw_font(badge_eink_fb, 16, 8+8*channel, BADGE_EINK_WIDTH-32, text, 46 | FONT_FULL_WIDTH | FONT_MONOSPACE | FONT_INVERT); 47 | ets_printf("%s\n", text); 48 | } 49 | 50 | /* update display */ 51 | badge_eink_display(badge_eink_fb, DISPLAY_FLAG_LUT(0)); 52 | 53 | // wait 1 second 54 | if (badge_input_get_event(1000) != 0) 55 | return; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /main/demo_test_adc.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_TEST_ADC_H 2 | #define DEMO_TEST_ADC_H 3 | 4 | #include "sdkconfig.h" 5 | 6 | extern void demoTestAdc(void); 7 | 8 | #endif // DEMO_TEST_ADC_H 9 | -------------------------------------------------------------------------------- /main/demo_text1.c: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | void 12 | demoText1(void) { 13 | esp_err_t err = badge_eink_fb_init(); 14 | assert( err == ESP_OK ); 15 | 16 | /* draw test pattern */ 17 | { 18 | int y; 19 | for (y=0; y 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | void 12 | demoText2(void) { 13 | esp_err_t err = badge_eink_fb_init(); 14 | assert( err == ESP_OK ); 15 | 16 | /* draw test pattern */ 17 | { 18 | int y; 19 | for (y=0; y 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "demo_ugfx.h" 10 | 11 | font_t roboto; 12 | font_t robotoBlackItalic; 13 | font_t permanentMarker; 14 | 15 | const char* displayNames[] = { 16 | "Kartoffel", 17 | "Sebastius", 18 | "Boekenwuurm", 19 | "Attilla", 20 | "Stitch", 21 | "tsd", 22 | "Sprite_TM", 23 | "Underhand", 24 | "MarkusBec", 25 | "Roosted", 26 | "the_JinX", 27 | "realitygaps", 28 | "raboof" 29 | }; 30 | 31 | #define numNames (sizeof(displayNames) / sizeof (const char*)) 32 | 33 | GEventToggle ptoggle; 34 | 35 | void showDemo(uint8_t name, color_t front, color_t back) { 36 | ets_printf("Getting toggle status\n"); 37 | if (!ginputGetToggleStatus(BADGE_BUTTON_UP, &ptoggle)) { 38 | ets_printf("Error getting toggle status\n"); 39 | } else { 40 | if (ptoggle.on) { 41 | ets_printf("button was pressed\n"); 42 | } else { 43 | ets_printf("button was not pressed\n"); 44 | } 45 | } 46 | 47 | gdispClear(back); 48 | gdispDrawString(150, 25, "STILL", robotoBlackItalic, front); 49 | gdispDrawString(130, 50, displayNames[name], permanentMarker, front); 50 | // underline: 51 | gdispDrawLine(127 + 3, 50 + 22, 52 | 127 + 3 + gdispGetStringWidth(displayNames[name], permanentMarker) + 14, 50 + 22, 53 | front); 54 | // cursor: 55 | gdispDrawLine(127 + 3 + gdispGetStringWidth(displayNames[name], permanentMarker) + 10, 50 + 2, 56 | 127 + 3 + gdispGetStringWidth(displayNames[name], permanentMarker) + 10, 50 + 22 - 2, 57 | front); 58 | gdispDrawString(140, 75, "Anyway", robotoBlackItalic, front); 59 | gdispDrawCircle(60, 60, 50, front); 60 | gdispFlush(); 61 | } 62 | 63 | void demoUgfx() { 64 | GListener pl; 65 | GEvent* event; 66 | 67 | ets_printf("Initializing gfx\n"); 68 | gfxInit(); 69 | ets_printf("Initialized gfx\n"); 70 | 71 | GSourceHandle upHandle = ginputGetToggle(BADGE_BUTTON_UP); 72 | 73 | geventListenerInit(&pl); 74 | geventAttachSource(&pl, upHandle, GLISTEN_TOGGLE_ON|GLISTEN_TOGGLE_OFF); 75 | 76 | roboto = gdispOpenFont("Roboto_Regular12"); 77 | robotoBlackItalic = gdispOpenFont("Roboto_BlackItalic24"); 78 | permanentMarker = gdispOpenFont("PermanentMarker22"); 79 | 80 | ets_printf("Clearing\n"); 81 | 82 | gdispClear(Black); 83 | gdispFlush(); 84 | 85 | while (1) { 86 | uint8_t i; 87 | for (i = 0; i < numNames; i++) { 88 | ets_printf("Make it White\n"); 89 | showDemo(i, Black, White); 90 | ets_printf("Take 5\n"); 91 | ets_printf("Waiting for 'up'\n"); 92 | if ((event = geventEventWait(&pl, 5000))) { 93 | ets_printf("Got 'up' event\n"); 94 | } else { 95 | ets_printf("Timeout without 'up' event\n"); 96 | } 97 | 98 | ets_printf("Paint it Black\n"); 99 | showDemo(i, White, Black); 100 | ets_printf("Take 5\n"); 101 | ets_printf("Waiting for 'up'\n"); 102 | if ((event = geventEventWait(&pl, 5000))) { 103 | ets_printf("Got 'up' event\n"); 104 | } else { 105 | ets_printf("Timeout without 'up' event\n"); 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /main/demo_ugfx.h: -------------------------------------------------------------------------------- 1 | #ifndef DEMO_UGFX_H 2 | #define DEMO_UGFX_H 3 | 4 | #include "sdkconfig.h" 5 | 6 | extern void demoUgfx(void); 7 | 8 | #endif // DEMO_UGFX_H 9 | -------------------------------------------------------------------------------- /main/img_hacking.h: -------------------------------------------------------------------------------- 1 | #ifndef IMG_HACKING_H 2 | #define IMG_HACKING_H 3 | 4 | #include 5 | 6 | /* 7 | * original image found on https://www.flickr.com/photos/adulau/9464930917/ 8 | * (Alexandre Dulaunoy) 9 | * 10 | * "Feel free to reuse, use and abuse my pictures under the CC-SA license, 11 | * the GNU Free Documentation License or the GNU General Public License." 12 | * 13 | * image is cropped and resized to 296x128 pixels. 14 | */ 15 | 16 | extern const uint8_t img_hacking[37888]; 17 | 18 | #endif // IMG_HACKING_H 19 | -------------------------------------------------------------------------------- /main/imgv2_hacking.h: -------------------------------------------------------------------------------- 1 | #ifndef IMGV2_HACKING_H 2 | #define IMGV2_HACKING_H 3 | 4 | #include 5 | 6 | extern const uint8_t imgv2_hacking[37888]; 7 | 8 | #endif // IMGV2_HACKING_H 9 | -------------------------------------------------------------------------------- /main/imgv2_menu.h: -------------------------------------------------------------------------------- 1 | #ifndef IMGV2_MENU_H 2 | #define IMGV2_MENU_H 3 | 4 | #include 5 | 6 | const uint8_t imgv2_menu[4736]; 7 | 8 | #endif // IMGV2_MENU_H 9 | -------------------------------------------------------------------------------- /main/imgv2_nick.h: -------------------------------------------------------------------------------- 1 | #ifndef IMGV2_NICK_H 2 | #define IMGV2_NICK_H 3 | 4 | #include 5 | 6 | const uint8_t imgv2_nick[4736]; 7 | 8 | #endif // IMGV2_NICK_H 9 | -------------------------------------------------------------------------------- /main/imgv2_sha.h: -------------------------------------------------------------------------------- 1 | #ifndef IMGV2_SHA_H 2 | #define IMGV2_SHA_H 3 | 4 | #include 5 | 6 | const uint8_t imgv2_sha[4736]; 7 | 8 | #endif // IMGV2_SHA_H 9 | -------------------------------------------------------------------------------- /main/imgv2_test.h: -------------------------------------------------------------------------------- 1 | #ifndef IMGV2_TEST_H 2 | #define IMGV2_TEST_H 3 | 4 | #include 5 | 6 | const uint8_t imgv2_test[4736]; 7 | 8 | #endif // IMGV2_TEST_H 9 | -------------------------------------------------------------------------------- /main/imgv2_weather.h: -------------------------------------------------------------------------------- 1 | #ifndef IMGV2_WEATHER_H 2 | #define IMGV2_WEATHER_H 3 | 4 | #include 5 | 6 | const uint8_t imgv2_weather[4736]; 7 | 8 | #endif // IMGV2_WEATHER_H 9 | -------------------------------------------------------------------------------- /main/leaseweb.h: -------------------------------------------------------------------------------- 1 | #ifndef LEASEWEB_H 2 | #define LEASEWEB_H 3 | 4 | #include 5 | 6 | const uint8_t leaseweb[4736]; 7 | 8 | #endif // LEASEWEB_H 9 | -------------------------------------------------------------------------------- /main/madison_gurkha.h: -------------------------------------------------------------------------------- 1 | #ifndef MG_LOGO_H 2 | #define MG_LOGO_H 3 | 4 | #include 5 | 6 | const uint8_t mg_logo[4736]; 7 | 8 | #endif // MG_LOGO_H 9 | -------------------------------------------------------------------------------- /partitions-16MB.csv: -------------------------------------------------------------------------------- 1 | # Name, Type, SubType, Offset, Size, Flags 2 | # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild 3 | 4 | nvs, data, nvs, 0x9000, 0x4000 5 | otadata, data, ota, 0xd000, 0x2000 6 | phy_init, data, phy, 0xf000, 0x1000 7 | ota_0, 0, ota_0, 0x10000, 1536K 8 | ota_1, 0, ota_1, , 1536K 9 | remfs, 0x20, 0x17, , 8M 10 | remfsota,0x20, 0x18, , 64K 11 | locfd, data, fat, , 4992K 12 | -------------------------------------------------------------------------------- /partitions-4MB.csv: -------------------------------------------------------------------------------- 1 | # Name, Type, SubType, Offset, Size, Flags 2 | # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild 3 | 4 | nvs, data, nvs, 0x9000, 0x4000 5 | otadata, data, ota, 0xd000, 0x2000 6 | phy_init, data, phy, 0xf000, 0x1000 7 | ota_0, 0, ota_0, 0x10000, 1536K 8 | ota_1, 0, ota_1, , 1536K 9 | locfd, data, fat, , 960K 10 | -------------------------------------------------------------------------------- /pictures/font_16px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/pictures/font_16px.png -------------------------------------------------------------------------------- /pictures/font_8px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/pictures/font_8px.png -------------------------------------------------------------------------------- /pictures/hacking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/pictures/hacking.png -------------------------------------------------------------------------------- /pictures/pic_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/pictures/pic_1.png -------------------------------------------------------------------------------- /pictures/pic_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/pictures/pic_2.png -------------------------------------------------------------------------------- /pictures/pic_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/pictures/pic_3.jpg -------------------------------------------------------------------------------- /pictures/pic_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/pictures/pic_3.png -------------------------------------------------------------------------------- /pictures/pic_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/pictures/pic_4.png -------------------------------------------------------------------------------- /pictures/pic_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SHA2017-badge/Firmware/e9c4b2ab7bd6546b190b88274eda5d3c7327e23c/pictures/pic_5.png -------------------------------------------------------------------------------- /set_env.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd esp-idf 4 | export IDF_PATH=$(pwd) 5 | export ESPIDF=$(pwd) 6 | source add_path.sh 7 | cd - 8 | 9 | if [ -f custom_env.sh ]; then 10 | . custom_env.sh 11 | fi 12 | 13 | # Anything added to the PATH in custom_env.sh will take precedence 14 | # to the bundled toolchain: 15 | export PATH=$PATH:$(pwd)/xtensa-esp32-elf/bin 16 | 17 | # Some shells, like zsh, will cache path lookups, so after changing PATH we 18 | # need to refresh the hash: 19 | hash -r &>/dev/null || true 20 | -------------------------------------------------------------------------------- /tools/font2h.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | use Image::Magick; 5 | use Getopt::Std; 6 | 7 | sub VERSION_MESSAGE { } 8 | sub HELP_MESSAGE { 9 | die "Usage: $0 [-h ] [-w ] [-v ] [-d ] \n" 10 | } 11 | 12 | my %opts; 13 | $Getopt::Std::STANDARD_HELP_VERSION = 1; 14 | getopts('d:h:w:v:', \%opts); 15 | 16 | my $height = $opts{h} // 8; 17 | my $width = $opts{w} // $height; 18 | my $varname = $opts{v} // "font_".$height."px"; 19 | my $defname = $opts{d} // uc($varname); 20 | 21 | my $file_in = shift // HELP_MESSAGE(); 22 | my $file_out = shift // HELP_MESSAGE(); 23 | @ARGV && HELP_MESSAGE(); 24 | 25 | my $file_h; 26 | if ($file_out ne '-') { 27 | $file_h = $file_out; 28 | $file_h =~ s/\A.*\///s; 29 | $file_h .= '.h'; 30 | } 31 | 32 | my $height_b = ($height+7) >> 3; 33 | my $ch_first = 32; 34 | my $ch_last = 126; 35 | 36 | my $p = Image::Magick->new; 37 | $p->Read($file_in eq '-' ? '/dev/stdin' : $file_in); 38 | 39 | my $xbox = $p->Get('width') / 16; # 8; 40 | my $ybox = $p->Get('height') / 6; # 10; 41 | 42 | my $cpos = 0; 43 | my @chars; 44 | 45 | my $out_h = ''; 46 | $out_h .= "#ifndef ".$defname."_H\n"; 47 | $out_h .= "#define ".$defname."_H\n"; 48 | $out_h .= "\n"; 49 | $out_h .= "#include \n"; 50 | $out_h .= "\n"; 51 | $out_h .= "#define ".$defname."_FIRST $ch_first\n"; 52 | $out_h .= "#define ".$defname."_LAST $ch_last\n"; 53 | $out_h .= "#define ".$defname."_WIDTH $width\n"; 54 | $out_h .= "#define ".$defname."_HEIGHT $height_b\n"; 55 | $out_h .= "\n"; 56 | 57 | my $out_c = ''; 58 | $out_c .= "#include \n"; 59 | $out_c .= "\n#include \"$file_h\"\n" if defined $file_h; 60 | $out_c .= "\n"; 61 | $out_c .= "const uint8_t ".$varname."_data[".($width*$height_b*($ch_last+1-$ch_first))."] = {\n"; 62 | $out_h .= "extern const uint8_t ".$varname."_data[".($width*$height_b*($ch_last+1-$ch_first))."];\n"; 63 | for (my $ch=$ch_first; $ch<=$ch_last; $ch++) { 64 | my $pos_x = ($ch & 15) * $xbox; 65 | my $pos_y = (($ch >> 4)-2) * $ybox; 66 | 67 | my @n; 68 | my $x; 69 | for ($x=0; $x<=$width; $x++) { 70 | my @pix = $p->GetPixel(x => ($pos_x+$x), y => ($pos_y)); 71 | last if $pix[1] == 0; 72 | my $n=0; 73 | for (my $y=$height-1; $y>=0; $y--) { 74 | @pix = $p->GetPixel(x => ($pos_x+$x), y => ($pos_y+$y)); 75 | $n *= 2; 76 | $n += $pix[0]; 77 | } 78 | my @nn; 79 | for (my $i=0; $i<$height_b; $i++) { 80 | push @nn, sprintf('0x%02x', $n & 0xff); 81 | $n >>= 8; 82 | } 83 | push @n, reverse @nn; 84 | } 85 | die "character $ch too wide.\n" if @n > $width*$height_b; 86 | my $indent = ($width - $x) >> 1; 87 | unshift @n, ('0x00') x ($indent*$height_b); 88 | push @chars, [ $x, $indent ]; 89 | while (@n < $width*$height_b) { push @n, '0x00' } 90 | $out_c .= "\t".join(', ', @n).",\n"; 91 | } 92 | $out_c .= "};\n"; 93 | $out_c .= "\n"; 94 | $out_c .= "const uint8_t ".$varname."_width[".($ch_last+1-$ch_first)."] = {\n"; 95 | $out_h .= "extern const uint8_t ".$varname."_width[".($ch_last+1-$ch_first)."];\n"; 96 | my @n; 97 | foreach my $c (@chars) { 98 | my ($clen, $indent) = @$c; 99 | push @n, sprintf('0x%02x', ($indent << 4) | $clen); 100 | if (@n >= 16) { 101 | $out_c .= "\t".join(', ', @n).",\n"; 102 | splice @n, 0, 16; 103 | } 104 | } 105 | $out_c .= "\t".join(', ', @n).",\n" if @n; 106 | $out_c .= "};\n"; 107 | $out_h .= "\n"; 108 | $out_h .= "#endif // ".$defname."_H\n"; 109 | 110 | if ($file_out eq '-') { 111 | print $out_c; 112 | } else { 113 | open F, '>', $file_out.'.c' or die; 114 | print F $out_c; 115 | close F; 116 | open F, '>', $file_out.'.h' or die; 117 | print F $out_h; 118 | close F; 119 | } 120 | -------------------------------------------------------------------------------- /tools/gen_fonts_h: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | destpath=../components/epd 4 | 5 | ./font2h.pl -w 6 -h 8 ../pictures/font_8px.png $destpath/font_8px 6 | ./font2h.pl -w 12 -h 16 ../pictures/font_16px.png $destpath/font_16px 7 | -------------------------------------------------------------------------------- /tools/gen_pictures_h: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | cd ../main 6 | ../tools/png_to_c_v2.pl -b ../pictures/pic_1.png imgv2_sha imgv2_sha.c 7 | ../tools/png_to_c_v2.pl -b ../pictures/pic_2.png imgv2_menu imgv2_menu.c 8 | ../tools/png_to_c_v2.pl -b ../pictures/pic_3.png imgv2_nick imgv2_nick.c 9 | ../tools/png_to_c_v2.pl -b ../pictures/pic_4.png imgv2_weather imgv2_weather.c 10 | ../tools/png_to_c_v2.pl -b ../pictures/pic_5.png imgv2_test imgv2_test.c 11 | -------------------------------------------------------------------------------- /tools/graphLUT.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | use Image::Magick; 5 | 6 | my %lut = ( 7 | 'fast' => [ 8 | # VS 9 | 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | # TP 12 | 0x13, 0x14, 0x44, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | ], 14 | 'slow' => [ 15 | # VS 16 | 0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, 0x66, 0x69, 17 | 0x69, 0x59, 0x58, 0x99, 0x99, 0x88, 0x00, 0x00, 0x00, 0x00, 18 | # TP 19 | 0xF8, 0xB4, 0x13, 0x51, 0x35, 0x51, 0x51, 0x19, 0x01, 0x00, 20 | ], 21 | ); 22 | 23 | foreach my $type (sort keys %lut) { 24 | my @raw = @{ $lut{$type} }; 25 | my @tp = map { ( $_ & 15, $_ >> 4 ) } splice @raw, 20, 10; 26 | my @vs = map { [ $_ & 3, ($_ >> 2) & 3, ($_ >> 4) & 3, $_ >> 6 ] } @raw; 27 | print "$type:\n"; 28 | my @ch = ("\e[0;1;30m\xc2\xb7\e[0m", '+', '-', '?'); 29 | print " + + - -\n"; 30 | for (my $i=0; $i<20; $i++) { 31 | printf "phase %02u: %s %s %s %s (%u cycles)\n", 32 | $i+1, 33 | $ch[$vs[$i][0]], 34 | $ch[$vs[$i][1]], 35 | $ch[$vs[$i][2]], 36 | $ch[$vs[$i][3]], 37 | $tp[$i]; 38 | } 39 | print " + - + -\n"; 40 | } 41 | -------------------------------------------------------------------------------- /tools/png_to_c_v2.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | use Image::Magick; 5 | use Getopt::Std; 6 | 7 | sub VERSION_MESSAGE { } 8 | sub HELP_MESSAGE { 9 | die "Usage: $0 [-b] [-w ] \n"; 10 | } 11 | 12 | my %opts = ( w => 16 ); 13 | $Getopt::Std::STANDARD_HELP_VERSION = 1; 14 | getopts('bw:', \%opts); 15 | 16 | my $file_in = shift // HELP_MESSAGE(); 17 | my $varname = shift // HELP_MESSAGE(); 18 | my $file_out = shift // HELP_MESSAGE(); 19 | @ARGV && HELP_MESSAGE(); 20 | 21 | my $num = $opts{w}; 22 | die "invalid variable name.\n" unless $varname =~ /\A[A-Za-z_][0-9A-Za-z_]*\z/; 23 | die "filename doesn't end with '.c'\n" unless $file_out =~ s/\.c\z//; 24 | 25 | my $p = Image::Magick->new; 26 | $p->Read($file_in eq '-' ? '/dev/stdin' : $file_in); 27 | 28 | # check dimensions of image 29 | die "Image is not 296x128.\n" 30 | unless $p->Get("Width") == 296 && $p->Get("Height") == 128; 31 | 32 | my $bin = ''; 33 | for (my $y=0; $y<128; $y++) { 34 | for (my $x=0; $x<296; $x++) { 35 | my @pix = $p->GetPixel(x => $x, y => $y); 36 | my $c = int($pix[0] * 255 + 0.5); 37 | $c = 0 if $c < 0; 38 | $c = 255 if $c > 255; 39 | if ($opts{b}) { 40 | vec($bin, $y*296+$x, 1) = $c >> 7; 41 | } else { 42 | $bin .= chr($c); 43 | } 44 | } 45 | } 46 | 47 | my $out_h = ''; 48 | $out_h .= '#ifndef '.uc($varname)."_H\n"; 49 | $out_h .= '#define '.uc($varname)."_H\n"; 50 | $out_h .= "\n"; 51 | $out_h .= "#include \n"; 52 | $out_h .= "\n"; 53 | $out_h .= "const uint8_t $varname\[".length($bin)."\];\n"; 54 | $out_h .= "\n"; 55 | $out_h .= '#endif // '.uc($varname)."_H\n"; 56 | 57 | my $out_c = ''; 58 | $out_c .= "#include \"$file_out\.h\"\n"; 59 | $out_c .= "\n"; 60 | $out_c .= "const uint8_t $varname\[".length($bin)."\] = {\n"; 61 | while ($bin ne '') { 62 | $out_c .= " ".join('', map { "0x$_," } unpack '(H2)*', substr($bin, 0, $num, ''))."\n"; 63 | } 64 | $out_c .= "};\n"; 65 | 66 | open my $f, '>', $file_out.'.h'; 67 | print $f $out_h; 68 | close $f; 69 | 70 | open $f, '>', $file_out.'.c'; 71 | print $f $out_c; 72 | close $f; 73 | 74 | -------------------------------------------------------------------------------- /tools/raw2h.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | use Getopt::Std; 5 | 6 | sub VERSION_MESSAGE { } 7 | sub HELP_MESSAGE { 8 | die "Usage: $0 [-i ] [-o ] [-v ] [-w ]\n"; 9 | } 10 | 11 | my %opts; 12 | $Getopt::Std::STANDARD_HELP_VERSION = 1; 13 | getopts('i:o:v:w:', \%opts); 14 | 15 | my $file_in = $opts{i}; 16 | my $file_out = $opts{o}; 17 | my $varname = $opts{v} // die "Variable name not set.\n"; 18 | my $num = $opts{w} // 16; 19 | die "bytes per line is not a positive integer.\n" unless $num =~ /\A[1-9]\d*\z/; 20 | 21 | my $bin; 22 | if (defined $file_in) { 23 | open F, '<', $file_in or die; 24 | $bin = do { local $/; }; 25 | close F; 26 | } else { 27 | $bin = do { local $/; }; 28 | } 29 | 30 | my $out = ''; 31 | $out .= "const uint8_t $varname\[".length($bin)."\] = {\n"; 32 | while ($bin ne '') { 33 | $out .= " ".join('', map { "0x$_," } unpack '(H2)*', substr($bin, 0, $num, ''))."\n"; 34 | } 35 | $out .= "};\n"; 36 | 37 | if (defined $file_out) { 38 | open F, '>', $file_out or die; 39 | print F $out; 40 | close F; 41 | } else { 42 | print $out; 43 | } 44 | --------------------------------------------------------------------------------