Merge branch 'example/badge_demo' into 'main'
Add Espressif Badge demo See merge request app-frameworks/esp-matter!551
@@ -80,3 +80,9 @@ examples/sleepy_device:
|
||||
- if: IDF_TARGET in ["esp32h2"]
|
||||
temporary: true
|
||||
reason: the other targets are not tested yet
|
||||
|
||||
examples/demo/badge:
|
||||
enable:
|
||||
- if: IDF_TARGET in ["esp32"]
|
||||
temporary: true
|
||||
reason: the other targets are not tested yet
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# ESP32 Name Badge
|
||||
|
||||
<div align="center">
|
||||
<img src="./Images/name_badge_10.jpg" width="300" />
|
||||
</div>
|
||||
|
||||
|
||||
---
|
||||
ESP32 Name Badge is a e-ink Name badge, designed for -event- on -date-. ESP32 Name Badge displays user-customed text via a phone app, and pinned onto your clothing, suitable for events. It is a brooch-type name badge based on DFROBOT's 2.13" e-ink Display Module for ESP32 (SKU:DFR0676). This repository will include all the instructions to replicate an ESP32 Name Badge yourself.
|
||||
|
||||
---
|
||||
|
||||
## Materials and Equipment
|
||||
1. DFROBOT's 2.13" e-ink Display Module for ESP32
|
||||
2. 3D Printer
|
||||
3. M2 brass insert nut, 3.2mm outer diameter (qty: 6)
|
||||
4. M2 Phillips head screw (qty: 6)
|
||||
5. brooch pin, 20mm
|
||||
|
||||
> **Note**
|
||||
3D Printer used in this guide is a DLP 3D Printer. Your results may vary with different 3D Printers, such as FDM 3D printer. For users without 3D printers, do consider reaching out to 3D Printing services locally or online.
|
||||
|
||||
## Instructions
|
||||
1. Download the STL file, and send for 3D printing.
|
||||
|
||||
<img src="./Images/name_badge_print.jpg" width="300" />
|
||||
|
||||
2. Force fit the 6 x brass insert nut.
|
||||
|
||||
<img src="./Images/name_badge_01.jpg" height="200" />
|
||||
<img src="./Images/name_badge_02.jpg" height="200" />
|
||||
|
||||
|
||||
3. Assemble DFROBOT's 2.13" e-ink Display Module for ESP32
|
||||
onto the case, using 4 x screws.
|
||||
|
||||
<img src="./Images/name_badge_03.jpg" height="200" />
|
||||
|
||||
4. Assemble brooch pin onto the case, using 2 x screws.
|
||||
|
||||
<img src="./Images/name_badge_04.jpg" height="200" />
|
||||
|
||||
5. Flash the firmware onto module via micro-USB.
|
||||
|
||||
<img src="./Images/name_badge_flash.jpg" height="200" />
|
||||
|
||||
6. You have completed building the ESP32 Name Badge.
|
||||
|
||||
<img src="./Images/name_badge_05.jpg" height="200" />
|
||||
|
||||
## Other Notes
|
||||
* Brass insert tolerance may be an issue with different sources. Do take note of this issue and troubleshoot accordingly.
|
||||
* Pin brooch used in this build is a 20mm version, with 2 x 2mm diameter hole, 7mm centre to centre distance.
|
||||
* More information about DFROBOT's 2.13" e-ink Display Module for ESP32 can be found in the following link: https://www.dfrobot.com/product-2101.html
|
||||
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,46 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
if(NOT DEFINED ENV{ESP_MATTER_PATH})
|
||||
message(FATAL_ERROR "Please set ESP_MATTER_PATH to the path of esp-matter repo")
|
||||
endif(NOT DEFINED ENV{ESP_MATTER_PATH})
|
||||
|
||||
if(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH})
|
||||
if("${IDF_TARGET}" STREQUAL "esp32" OR "${IDF_TARGET}" STREQUAL "")
|
||||
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32_devkit_c)
|
||||
else()
|
||||
message(FATAL_ERROR "Espressif Badge is only supported on ESP32 target")
|
||||
endif()
|
||||
endif(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH})
|
||||
|
||||
set(PROJECT_VER "1.0")
|
||||
set(PROJECT_VER_NUMBER 1)
|
||||
|
||||
set(ESP_MATTER_PATH $ENV{ESP_MATTER_PATH})
|
||||
set(MATTER_SDK_PATH ${ESP_MATTER_PATH}/connectedhomeip/connectedhomeip)
|
||||
|
||||
# This should be done before using the IDF_TARGET variable.
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
include($ENV{ESP_MATTER_DEVICE_PATH}/esp_matter_device.cmake)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS
|
||||
"${ESP_MATTER_PATH}/examples/common"
|
||||
"${MATTER_SDK_PATH}/config/esp32/components"
|
||||
"${ESP_MATTER_PATH}/components"
|
||||
"${ESP_MATTER_PATH}/device_hal/device"
|
||||
${extra_components_dirs_append})
|
||||
|
||||
project(demo-badge)
|
||||
|
||||
# WARNING: This is just an example for using key for decrypting the encrypted OTA image
|
||||
# Please do not use it as is.
|
||||
if(CONFIG_ENABLE_ENCRYPTED_OTA)
|
||||
target_add_binary_data(light.elf "esp_image_encryption_key.pem" TEXT)
|
||||
endif()
|
||||
|
||||
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DCHIP_HAVE_CONFIG_H" APPEND)
|
||||
idf_build_set_property(C_COMPILE_OPTIONS "-Os" APPEND)
|
||||
# For RISCV chips, project_include.cmake sets -Wno-format, but does not clear various
|
||||
# flags that depend on -Wformat
|
||||
idf_build_set_property(COMPILE_OPTIONS "-Wno-format-nonliteral;-Wno-format-security" APPEND)
|
||||
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 216 KiB |
|
After Width: | Height: | Size: 399 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 229 KiB |
@@ -0,0 +1,160 @@
|
||||
# Badge
|
||||
|
||||
|  |  |
|
||||
| -------- | ------- |
|
||||
|
||||
# Table of Contents
|
||||
- [Badge](#badge)
|
||||
- [Espressif Digital Badge](#espressif-digital-badge)
|
||||
- [File Structure](#file-structure)
|
||||
- [Features](#features)
|
||||
- [How to use](#how-to-use)
|
||||
- [Commands](#commands)
|
||||
- [Set the attribute](#set-the-attribute)
|
||||
- [Console](#console)
|
||||
- [CHIP-TOOL](#chip-tool)
|
||||
- [3D Design](#3d-design)
|
||||
- [Creating the custom fonts](#creating-the-custom-fonts)
|
||||
- [Acknowledgement](#acknowledgement)
|
||||
|
||||
# Espressif Digital Badge
|
||||
|
||||
The Espressif Digital Badge serves as an intelligent e-ink display name badge, integrating a vCard QR code for effortless contact information sharing. This badge showcases user-customized attributes via a Matter application and can be easily affixed to clothing, making it ideal for various events. As a Matter-compatible accessory, it can be configured using any Matter-enabled phone application to personalize attributes. Crafted in the form of a brooch, it utilizes [DFROBOT's 2.13" e-ink Display Module for ESP32](https://wiki.dfrobot.com/e-Ink_Display_Module_for_ESP32_SKU_DFR0676). This repository comprehensively outlines all necessary instructions for replicating the badge independently.
|
||||
|
||||
The implementation involves the establishment of a custom cluster (`cluster_id: 0x131BFC03`) within the `Root Node`. This cluster encompasses five distinct custom attributes, each serving a specific purpose:
|
||||
|
||||
| Property | Attribute Id |
|
||||
|----------|----------|
|
||||
| Name | 0x0000 |
|
||||
| Company Name | 0x0001 |
|
||||
| Email | 0x0002 |
|
||||
| Contact | 0x0003 |
|
||||
| Event Name | 0x0004 |
|
||||
|
||||
*(Note: The maximum size of each attributes mentioned above is 32 bytes i.e. the maximum supported character length is 32)*
|
||||
|
||||
The Badge cluster also features a `command` at id 0x0000, to set all the aforementioned attributes in one go.
|
||||
|
||||
## File Structure
|
||||
```
|
||||
.
|
||||
├── 3D_design_files # Contains 3D design files for the badge
|
||||
├── CMakeLists.txt
|
||||
├── components
|
||||
│ ├── epaper # Epaper Display Library
|
||||
│ └── qrcode # QRcode Library for vcard
|
||||
├── Demonstration_result # Demonstration Results
|
||||
├── main
|
||||
│ ├── app_driver.cpp # Contains all the driver related function calls
|
||||
│ ├── app_main.cpp # Contains all the matter handling function calls
|
||||
│ ├── app_priv.h # Contains the shared private variables of app_driver.cpp and app_main.cpp
|
||||
│ ├── CMakeLists.txt
|
||||
│ └── idf_component.yml
|
||||
├── partitions.csv # Flash partition structure
|
||||
├── README.md
|
||||
└── sdkconfig.defaults # Required configuration to build the project
|
||||
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
* The application generates a QR code representation of the vCard containing the aforementioned attributes and displays it on the E-Ink display. This QR code serves as a convenient means for storing and retrieving data by simply scanning the code.
|
||||
|
||||
* If uncommissioned, badge displays commission QR Code and manual pairing code as shown below.
|
||||
|
||||

|
||||
*Badge Commissioning Window*
|
||||
|
||||
* In the absence of custom attribute configurations, the digital badge seamlessly functions as a matter on/off light, as demonstrated below.
|
||||
|
||||
|  |  |
|
||||
| -------- | ------- |
|
||||
| Badge Light On | Badge Light Off |
|
||||
|
||||
* For setting just name and company name, `NodeLabel` can be set in the format as "{Name}/{Company Name}"
|
||||
|
||||
## How to use
|
||||
Espressif Badge currently only supports esp32 based targets.
|
||||
|
||||
* Build the badge firmware:
|
||||
|
||||
```sh
|
||||
idf.p build
|
||||
```
|
||||
|
||||
* flash and monitor:
|
||||
|
||||
```sh
|
||||
idf.py -p <PORT> flash monitor
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
### Set the attribute
|
||||
|
||||
In this illustration, the Matter console has been activated, offering a streamlined interface for both configuring and retrieving attribute values. Alternatively, the chip-tool presents a secondary method for achieving the same objectives.
|
||||
|
||||
#### Console
|
||||
|
||||
* To set a specific attribute, utilize the following command (refer to the [Espressif Digital Badge](#espressif-digital-badge) for attribute details).
|
||||
|
||||
```sh
|
||||
matter esp attribute set 0x0 0x131BFC03 <attribute_id> <attribute value>
|
||||
```
|
||||
for example to change the Name on the badge, it requires to write the attribute `0x0000`, so the command will be:
|
||||
|
||||
```sh
|
||||
matter esp attribute set 0x0 0x131BFC03 0x0000 "Espressif Systems"
|
||||
```
|
||||
|
||||
* A custom console command `change_name` has also been added to display the name, company_name etc.. without commissioning with the matter:
|
||||
|
||||
```sh
|
||||
matter esp change_name "{name}/{company_name}/{email}/{contact}/{event_name}"
|
||||
```
|
||||
Example:
|
||||
```sh
|
||||
matter esp change_name "John Doe/Company Name/john.doe@espressif.com/123456789/Special Events"
|
||||
```
|
||||
|
||||
#### CHIP-TOOL
|
||||
|
||||
* Make sure to export the environment variables of ESP-MATTER to use the chip-tool
|
||||
|
||||
* Commission the device:
|
||||
```sh
|
||||
chip-tool pairing code-wifi 0x7289 <wifi-ssid> <wifi-password> MT:Y.K9042C00KA0648G00
|
||||
```
|
||||
|
||||
* After commissioning, individual custom attributes can be updated using the following command:
|
||||
```sh
|
||||
chip-tool any write-by-id 0x131BFC03 <attribute_id> '"<attribute_value>"' <destination_id> 0x0
|
||||
```
|
||||
|
||||
* To simultaneously update all attributes, one can employ the custom `command` at id 0x0000 as follows:
|
||||
|
||||
```sh
|
||||
chip-tool any command-by-id 0x131BFC03 0x0 '{"0":"<Name>","1":"<Company Name>","2":"<EMAIL>","3":"<Contact>","4":"<Event Name>"}' <destination_id> 0x0
|
||||
```
|
||||
|
||||
|
||||
## 3D Design
|
||||
|
||||
The design files for the badge can be found [here](./3D_design_files/) along with the [instructions](./3D_design_files/3D_Model_instructions.md).
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Generate and Add Custom Fonts</summary>
|
||||
|
||||
## Creating the custom fonts
|
||||
|
||||
* You can refer [this](https://www.cnx-software.com/2020/06/19/fontedit-font-editor-targets-embedded-systems-with-led-lcd-or-e-paper-displays) website to develop your own fonts or convert existing fonts to the c source code as required by this project.
|
||||
* Then copy the c source code of the font from the `FontEdit` app and paste it in [epaper_fonts.c](./components/epaper/epaper_font.c)
|
||||
* Create a `epaper_font_t` variable and add the height and width (refer it from FontEdit)
|
||||
|
||||
</details>
|
||||
|
||||
## Acknowledgement
|
||||
* A special thanks to [Richard Moore](https://github.com/ricmoo) for the QRCode library.
|
||||
* Shout out to `DFROBOT` for their excellent hardware design for the badge.
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (c) 2023 Project CHIP Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<configurator>
|
||||
<domain name="CHIP"/>
|
||||
<cluster>
|
||||
|
||||
<name>Espressif Badge</name>
|
||||
<domain>CHIP</domain>
|
||||
<code>0x131BFC03</code>
|
||||
<define>BADGE_CLUSTER</define>
|
||||
|
||||
<description>Attributes and commands for badge cluster.</description>
|
||||
|
||||
<attribute side="server" code="0x0000" define="Name" type="char_string" length="32" writable="true">Name</attribute>
|
||||
<attribute side="server" code="0x0001" define="Company Name" type="char_string" length="32" writable="true">Company Name</attribute>
|
||||
<attribute side="server" code="0x0002" define="Email" type="char_string" length="32" writable="true">Email</attribute>
|
||||
<attribute side="server" code="0x0003" define="Contact" type="char_string" length="32" writable="true">Contact</attribute>
|
||||
<attribute side="server" code="0x0004" define="Event Name" type="char_string" length="32" writable="true">Event Name</attribute>
|
||||
|
||||
<command source="client" code="0x00" name="Configuration" optional="false">
|
||||
<description>Badge Command</description>
|
||||
<arg name="ConfigurationArg" type="char_string"/>
|
||||
</command>
|
||||
|
||||
</cluster>
|
||||
</configurator>
|
||||
@@ -0,0 +1,9 @@
|
||||
set(COMPONENT_SRCS "epaper.c"
|
||||
"epaper_font.c"
|
||||
"imagedata.c"
|
||||
"lowpower_evb_epaper.cpp")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
|
||||
set(COMPONENT_REQUIRES driver qrcode)
|
||||
|
||||
register_component()
|
||||
@@ -0,0 +1,954 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <stdio.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/ringbuf.h"
|
||||
#include "epaper.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char* TAG = "epaper";
|
||||
uint8_t _buffer[4000] = {0x00};
|
||||
bool iot_power_is_on;
|
||||
int16_t iot_current_page;
|
||||
|
||||
#define EPAPER_CS_SETUP_NS 55
|
||||
#define EPAPER_CS_HOLD_NS 60
|
||||
#define EPAPER_1S_NS 1000000000
|
||||
#define EPAPER_QUE_SIZE_DEFAULT 10
|
||||
|
||||
const unsigned char lut_partial[] =
|
||||
{
|
||||
0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x40, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2,
|
||||
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0,
|
||||
};
|
||||
|
||||
#define EPAPER_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux)
|
||||
#define EPAPER_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux)
|
||||
|
||||
bool iot_using_partial_mode;
|
||||
// LCD data/command
|
||||
typedef struct {
|
||||
uint8_t dc_io;
|
||||
uint8_t dc_level;
|
||||
} epaper_dc_t;
|
||||
|
||||
typedef struct {
|
||||
spi_device_handle_t bus;
|
||||
epaper_conf_t pin; /* EPD properties */
|
||||
epaper_paint_t paint; /* Paint properties */
|
||||
epaper_dc_t dc;
|
||||
SemaphoreHandle_t spi_mux;
|
||||
} epaper_dev_t;
|
||||
|
||||
/*This function is called (in irq context!) just before a transmission starts.
|
||||
It will set the D/C line to the value indicated in the user field */
|
||||
static void iot_epaper_pre_transfer_callback(spi_transaction_t *t)
|
||||
{
|
||||
epaper_dc_t *dc = (epaper_dc_t *) t->user;
|
||||
gpio_set_level((int)dc->dc_io, (int)dc->dc_level);
|
||||
}
|
||||
|
||||
static esp_err_t _iot_epaper_spi_send(spi_device_handle_t spi, spi_transaction_t* t)
|
||||
{
|
||||
return spi_device_transmit(spi, t);
|
||||
}
|
||||
|
||||
void iot_epaper_send(spi_device_handle_t spi, const uint8_t *data, int len, epaper_dc_t *dc)
|
||||
{
|
||||
esp_err_t ret;
|
||||
if (len == 0) {
|
||||
return; //no need to send anything
|
||||
}
|
||||
spi_transaction_t t = {
|
||||
.length = len * 8, // Len is in bytes, transaction length is in bits.
|
||||
.tx_buffer = data, // Data
|
||||
.user = (void *) dc, // D/C needs to be set to 1
|
||||
};
|
||||
ret = _iot_epaper_spi_send(spi, &t);
|
||||
assert(ret == ESP_OK); // Should have had no issues.
|
||||
}
|
||||
|
||||
static void iot_epaper_send_command(epaper_handle_t dev, unsigned char command)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
device->dc.dc_io = device->pin.dc_pin;
|
||||
device->dc.dc_level = device->pin.dc_lev_cmd;
|
||||
iot_epaper_send(device->bus, &command, 1, &device->dc);
|
||||
}
|
||||
|
||||
static void iot_epaper_send_byte(epaper_handle_t dev, const uint8_t data)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
device->dc.dc_io = device->pin.dc_pin;
|
||||
device->dc.dc_level = device->pin.dc_lev_data;
|
||||
iot_epaper_send(device->bus, &data, 1, &device->dc);
|
||||
}
|
||||
|
||||
static void iot_epaper_send_data(epaper_handle_t dev, const uint8_t *data, int length)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
device->dc.dc_io = device->pin.dc_pin;
|
||||
device->dc.dc_level = device->pin.dc_lev_data;
|
||||
// This SPI slave only support slow write mode
|
||||
// We can just send data byte by byte.
|
||||
int idx = 0;
|
||||
while(idx < length) {
|
||||
iot_epaper_send_byte(dev, data[idx++]);
|
||||
}
|
||||
}
|
||||
|
||||
static void iot_epaper_gpio_init(epaper_conf_t * pin)
|
||||
{
|
||||
esp_rom_gpio_pad_select_gpio(pin->cs_pin);
|
||||
gpio_set_direction(pin->cs_pin, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(pin->cs_pin, 1);
|
||||
|
||||
esp_rom_gpio_pad_select_gpio(pin->dc_pin);
|
||||
gpio_set_direction(pin->dc_pin, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(pin->dc_pin, 1);
|
||||
|
||||
esp_rom_gpio_pad_select_gpio(pin->reset_pin);
|
||||
gpio_set_direction(pin->reset_pin, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(pin->reset_pin, 1);
|
||||
|
||||
esp_rom_gpio_pad_select_gpio(pin->busy_pin);
|
||||
gpio_set_direction(pin->busy_pin, GPIO_MODE_INPUT);
|
||||
gpio_set_pull_mode(pin->busy_pin, GPIO_PULLUP_ONLY);
|
||||
}
|
||||
|
||||
static esp_err_t iot_epaper_spi_init(epaper_handle_t dev, spi_device_handle_t *e_spi, epaper_conf_t *pin)
|
||||
{
|
||||
esp_err_t ret;
|
||||
spi_bus_config_t buscfg = {
|
||||
.miso_io_num = -1, // set SPI MISO pin
|
||||
.mosi_io_num = pin->mosi_pin, // set SPI MOSI pin
|
||||
.sclk_io_num = pin->sck_pin, // set SPI CLK pin
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = 0, // max transfer size is 4k bytes
|
||||
};
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.clock_speed_hz = pin->clk_freq_hz, // SPI clock is 40 MHz
|
||||
.mode = 0, // SPI mode 0
|
||||
.spics_io_num = pin->cs_pin, // we will use external CS pin
|
||||
.cs_ena_pretrans = EPAPER_CS_SETUP_NS / (EPAPER_1S_NS / (pin->clk_freq_hz)) + 2,
|
||||
.cs_ena_posttrans = EPAPER_CS_HOLD_NS / (EPAPER_1S_NS / (pin->clk_freq_hz)) + 2,
|
||||
.queue_size = EPAPER_QUE_SIZE_DEFAULT, //
|
||||
.flags = (SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE), // ALWAYS SET to HALF DUPLEX MODE for display spi !!
|
||||
.pre_cb = iot_epaper_pre_transfer_callback, //Specify pre-transfer callback to handle D/C line
|
||||
};
|
||||
//Initialize the SPI bus
|
||||
ret = spi_bus_initialize(pin->spi_host, &buscfg, 1);
|
||||
assert(ret == ESP_OK);
|
||||
//Attach the EPD to the SPI bus
|
||||
ret = spi_bus_add_device(pin->spi_host, &devcfg, e_spi);
|
||||
assert(ret == ESP_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iot_epaper_epd_init(epaper_handle_t dev, uint8_t Data)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
/* EPD hardware init start */
|
||||
iot_epaper_reset(dev);
|
||||
iot_Init_Full(dev,0x03);
|
||||
|
||||
for (uint16_t x = 0; x < sizeof(_buffer); x++)
|
||||
{
|
||||
_buffer[x] = Data;
|
||||
}
|
||||
|
||||
//update
|
||||
iot_epaper_send_command(dev,0x24);
|
||||
for (uint16_t y = 0; y < GxDEPG0213BN_HEIGHT; y++)
|
||||
{
|
||||
for (uint16_t x = 0; x < GxDEPG0213BN_WIDTH / 8; x++)
|
||||
{
|
||||
uint16_t idx = y * (GxDEPG0213BN_WIDTH / 8) + x;
|
||||
uint8_t data = (idx < sizeof(_buffer)) ? _buffer[idx] : 0x00;
|
||||
iot_epaper_send_byte(dev,~data);
|
||||
}
|
||||
}
|
||||
iot_epaper_send_command(dev,0x26); // both buffers same for full b/w
|
||||
for (uint16_t y = 0; y < GxDEPG0213BN_HEIGHT; y++)
|
||||
{
|
||||
for (uint16_t x = 0; x < GxDEPG0213BN_WIDTH / 8; x++)
|
||||
{
|
||||
uint16_t idx = y * (GxDEPG0213BN_WIDTH / 8) + x;
|
||||
uint8_t data = (idx < sizeof(_buffer)) ? _buffer[idx] : 0x00;
|
||||
iot_epaper_send_byte(dev,~data);
|
||||
}
|
||||
}
|
||||
//update_full
|
||||
iot_Update_Full(dev);
|
||||
|
||||
//power off
|
||||
iot_PowerOff(dev);
|
||||
//esp_rom_delay_us(500000);
|
||||
iot_current_page = -1;
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
/* EPD hardware init end */
|
||||
}
|
||||
|
||||
epaper_handle_t iot_epaper_create(spi_device_handle_t bus, epaper_conf_t *epconf)
|
||||
{
|
||||
epaper_dev_t* dev = (epaper_dev_t*) calloc(1, sizeof(epaper_dev_t));
|
||||
dev->spi_mux = xSemaphoreCreateRecursiveMutex();
|
||||
iot_epaper_gpio_init(epconf);
|
||||
ESP_LOGI(TAG, "gpio init ok");
|
||||
if (bus) {
|
||||
dev->bus = bus;
|
||||
} else {
|
||||
iot_epaper_spi_init(dev, &dev->bus, epconf);
|
||||
ESP_LOGI(TAG, "spi init ok");
|
||||
}
|
||||
dev->pin = *epconf;
|
||||
iot_epaper_epd_init(dev, 0x00);
|
||||
return (epaper_handle_t) dev;
|
||||
}
|
||||
|
||||
esp_err_t iot_epaper_delete(epaper_handle_t dev, bool del_bus)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
iot_epaper_send_command(dev, E_PAPER_POWER_OFF);
|
||||
spi_bus_remove_device(device->bus);
|
||||
if (del_bus) {
|
||||
spi_bus_free(device->pin.spi_host);
|
||||
}
|
||||
vSemaphoreDelete(device->spi_mux);
|
||||
free(device);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int iot_epaper_get_width(epaper_handle_t dev)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
return device->paint.width;
|
||||
}
|
||||
|
||||
void iot_epaper_set_width(epaper_handle_t dev, int width)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
device->paint.width = width % 8 ? width + 8 - (width % 8) : width;
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
|
||||
}
|
||||
|
||||
int iot_epaper_get_height(epaper_handle_t dev)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
return device->paint.height;
|
||||
}
|
||||
|
||||
void iot_epaper_set_height(epaper_handle_t dev, int height)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
device->paint.height = height;
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
int iot_epaper_get_rotate(epaper_handle_t dev)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
return device->paint.Rotation;
|
||||
}
|
||||
|
||||
void iot_epaper_set_rotate(epaper_handle_t dev, int rotate)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
device->paint.Rotation = rotate;
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
void iot_epaper_clean_paint(epaper_handle_t dev, int colored)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
for (int x = 0; x < device->paint.width; x++) {
|
||||
for (int y = 0; y < device->paint.height; y++) {
|
||||
iot_drawPixel(dev, x, y, colored);
|
||||
}
|
||||
}
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: this displays a string on the frame buffer but not refresh
|
||||
*/
|
||||
void iot_epaper_draw_string(epaper_handle_t dev, int x, int y, const char* text, epaper_font_t* font, int colored)
|
||||
{
|
||||
const char* p_text = text;
|
||||
unsigned int counter = 0;
|
||||
int refcolumn = x;
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
/* Send the string character by character on EPD */
|
||||
while (*p_text != 0) {
|
||||
/* Display one character on EPD */
|
||||
iot_epaper_draw_char(dev, refcolumn, y, *p_text, font, colored);
|
||||
/* Decrement the column position by 16 */
|
||||
refcolumn += font->width;
|
||||
/* Point on the next character */
|
||||
p_text++;
|
||||
counter++;
|
||||
}
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: this draws a charactor on the frame buffer but not refresh
|
||||
*/
|
||||
void iot_epaper_draw_char(epaper_handle_t dev, int x, int y, char ascii_char, epaper_font_t* font, int colored)
|
||||
{
|
||||
int i, j;
|
||||
unsigned int char_offset = (ascii_char - ' ') * font->height * (font->width / 8 + (font->width % 8 ? 1 : 0));
|
||||
const unsigned char* ptr = &font->font_table[char_offset];
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
for (j = 0; j < font->height; j++) {
|
||||
for (i = 0; i < font->width; i++) {
|
||||
if (*ptr & (0x80 >> (i % 8))) {
|
||||
iot_drawPixel(dev, x + i, y + j, colored);
|
||||
}
|
||||
if (i % 8 == 7) {
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
if (font->width % 8 != 0) {
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: this draws a line on the frame buffer
|
||||
*/
|
||||
void iot_epaper_draw_line(epaper_handle_t dev, int x0, int y0, int x1, int y1,
|
||||
int colored)
|
||||
{
|
||||
/* Bresenham algorithm */
|
||||
int dx = x1 - x0 >= 0 ? x1 - x0 : x0 - x1;
|
||||
int sx = x0 < x1 ? 1 : -1;
|
||||
int dy = y1 - y0 <= 0 ? y1 - y0 : y0 - y1;
|
||||
int sy = y0 < y1 ? 1 : -1;
|
||||
int err = dx + dy;
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
while ((x0 != x1) && (y0 != y1)) {
|
||||
iot_drawPixel(dev, x0, y0, colored);
|
||||
if (2 * err >= dy) {
|
||||
err += dy;
|
||||
x0 += sx;
|
||||
}
|
||||
if (2 * err <= dx) {
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: this draws a horizontal line on the frame buffer
|
||||
*/
|
||||
void iot_epaper_draw_horizontal_line(epaper_handle_t dev, int x, int y, int width, int colored)
|
||||
{
|
||||
int i;
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
for (i = x; i < x + width; i++) {
|
||||
iot_drawPixel(dev, i, y, colored);
|
||||
}
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: this draws a vertical line on the frame buffer
|
||||
*/
|
||||
void iot_epaper_draw_vertical_line(epaper_handle_t dev, int x, int y, int height, int colored)
|
||||
{
|
||||
int i;
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
for (i = y; i < y + height; i++) {
|
||||
iot_drawPixel(dev, x, i, colored);
|
||||
}
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: this draws a rectangle
|
||||
*/
|
||||
void iot_epaper_draw_rectangle(epaper_handle_t dev, int x0, int y0, int x1, int y1, int colored)
|
||||
{
|
||||
int min_x, min_y, max_x, max_y;
|
||||
min_x = x1 > x0 ? x0 : x1;
|
||||
max_x = x1 > x0 ? x1 : x0;
|
||||
min_y = y1 > y0 ? y0 : y1;
|
||||
max_y = y1 > y0 ? y1 : y0;
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
iot_epaper_draw_horizontal_line(dev, min_x, min_y, max_x - min_x + 1, colored);
|
||||
iot_epaper_draw_horizontal_line(dev, min_x, max_y, max_x - min_x + 1, colored);
|
||||
iot_epaper_draw_vertical_line(dev, min_x, min_y, max_y - min_y + 1, colored);
|
||||
iot_epaper_draw_vertical_line(dev, max_x, min_y, max_y - min_y + 1, colored);
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: this draws a filled rectangle
|
||||
*/
|
||||
void iot_epaper_draw_filled_rectangle(epaper_handle_t dev, int x0, int y0, int x1, int y1, int colored)
|
||||
{
|
||||
int min_x, min_y, max_x, max_y;
|
||||
int i;
|
||||
min_x = x1 > x0 ? x0 : x1;
|
||||
max_x = x1 > x0 ? x1 : x0;
|
||||
min_y = y1 > y0 ? y0 : y1;
|
||||
max_y = y1 > y0 ? y1 : y0;
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
for (i = min_x; i <= max_x; i++) {
|
||||
iot_epaper_draw_vertical_line(dev, i, min_y, max_y - min_y + 1, colored);
|
||||
}
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: this draws a circle
|
||||
*/
|
||||
void iot_epaper_draw_circle(epaper_handle_t dev, int x, int y, int radius,
|
||||
int colored)
|
||||
{
|
||||
/* Bresenham algorithm */
|
||||
int x_pos = -radius;
|
||||
int y_pos = 0;
|
||||
int err = 2 - 2 * radius;
|
||||
int e2;
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
do {
|
||||
iot_drawPixel(dev, x - x_pos, y + y_pos, colored);
|
||||
iot_drawPixel(dev, x + x_pos, y + y_pos, colored);
|
||||
iot_drawPixel(dev, x + x_pos, y - y_pos, colored);
|
||||
iot_drawPixel(dev, x - x_pos, y - y_pos, colored);
|
||||
e2 = err;
|
||||
if (e2 <= y_pos) {
|
||||
err += ++y_pos * 2 + 1;
|
||||
if (-x_pos == y_pos && e2 <= x_pos) {
|
||||
e2 = 0;
|
||||
}
|
||||
}
|
||||
if (e2 > x_pos) {
|
||||
err += ++x_pos * 2 + 1;
|
||||
}
|
||||
} while (x_pos <= 0);
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: this draws a filled circle
|
||||
*/
|
||||
void iot_epaper_draw_filled_circle(epaper_handle_t dev, int x, int y, int radius, int colored)
|
||||
{
|
||||
/* Bresenham algorithm */
|
||||
int x_pos = -radius;
|
||||
int y_pos = 0;
|
||||
int err = 2 - 2 * radius;
|
||||
int e2;
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
do {
|
||||
iot_drawPixel(dev, x - x_pos, y + y_pos, colored);
|
||||
iot_drawPixel(dev, x + x_pos, y + y_pos, colored);
|
||||
iot_drawPixel(dev, x + x_pos, y - y_pos, colored);
|
||||
iot_drawPixel(dev, x - x_pos, y - y_pos, colored);
|
||||
iot_epaper_draw_horizontal_line(dev, x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored);
|
||||
iot_epaper_draw_horizontal_line(dev, x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored);
|
||||
e2 = err;
|
||||
if (e2 <= y_pos) {
|
||||
err += ++y_pos * 2 + 1;
|
||||
if (-x_pos == y_pos && e2 <= x_pos) {
|
||||
e2 = 0;
|
||||
}
|
||||
}
|
||||
if (e2 > x_pos) {
|
||||
err += ++x_pos * 2 + 1;
|
||||
}
|
||||
} while (x_pos <= 0);
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief wait until idle
|
||||
*/
|
||||
void iot_epaper_wait_idle(epaper_handle_t dev)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
while (gpio_get_level((gpio_num_t) device->pin.busy_pin) == 1) { //1: busy, 0: idle fixed
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
//ESP_LOGI(TAG, "Busy");
|
||||
}
|
||||
//ESP_LOGI(TAG, "Done!");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief setRamDataEntryMode
|
||||
*/
|
||||
void iot_setRamDataEntryMode(epaper_handle_t dev, uint8_t em)
|
||||
{
|
||||
const uint16_t xPixelsPar = GxDEPG0213BN_X_PIXELS - 1;
|
||||
const uint16_t yPixelsPar = GxDEPG0213BN_Y_PIXELS - 1;
|
||||
em = gx_uint16_min(em, 0x03);
|
||||
iot_epaper_send_command(dev,0x11);
|
||||
iot_epaper_send_byte(dev,em);
|
||||
switch (em)
|
||||
{
|
||||
case 0x00: // x decrease, y decrease
|
||||
iot_SetRamArea(dev,xPixelsPar / 8, 0x00, yPixelsPar % 256, yPixelsPar / 256, 0x00, 0x00); // X-source area,Y-gate area
|
||||
iot_SetRamPointer(dev,xPixelsPar / 8, yPixelsPar % 256, yPixelsPar / 256); // set ram
|
||||
break;
|
||||
case 0x01: // x increase, y decrease : as in demo code
|
||||
iot_SetRamArea(dev,0x00, xPixelsPar / 8, yPixelsPar % 256, yPixelsPar / 256, 0x00, 0x00); // X-source area,Y-gate area
|
||||
iot_SetRamPointer(dev,0x00, yPixelsPar % 256, yPixelsPar / 256); // set ram
|
||||
break;
|
||||
case 0x02: // x decrease, y increase
|
||||
iot_SetRamArea(dev,xPixelsPar / 8, 0x00, 0x00, 0x00, yPixelsPar % 256, yPixelsPar / 256); // X-source area,Y-gate area
|
||||
iot_SetRamPointer(dev,xPixelsPar / 8, 0x00, 0x00); // set ram
|
||||
break;
|
||||
case 0x03: // x increase, y increase : normal mode
|
||||
iot_SetRamArea(dev,0x00, xPixelsPar / 8, 0x00, 0x00, yPixelsPar % 256, yPixelsPar / 256); // X-source area,Y-gate area
|
||||
iot_SetRamPointer(dev,0x00, 0x00, 0x00); // set ram
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SetRamArea
|
||||
*/
|
||||
void iot_SetRamArea(epaper_handle_t dev, uint8_t Xstart, uint8_t Xend, uint8_t Ystart, uint8_t Ystart1, uint8_t Yend, uint8_t Yend1)
|
||||
{
|
||||
iot_epaper_send_command(dev,0x44);
|
||||
iot_epaper_send_byte(dev,Xstart);
|
||||
iot_epaper_send_byte(dev,Xend);
|
||||
iot_epaper_send_command(dev,0x45);
|
||||
iot_epaper_send_byte(dev,Ystart);
|
||||
iot_epaper_send_byte(dev,Ystart1);
|
||||
iot_epaper_send_byte(dev,Yend);
|
||||
iot_epaper_send_byte(dev,Yend1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SetRamPointer
|
||||
*/
|
||||
void iot_SetRamPointer(epaper_handle_t dev, uint8_t addrX, uint8_t addrY, uint8_t addrY1)
|
||||
{
|
||||
iot_epaper_send_command(dev,0x4e);
|
||||
iot_epaper_send_byte(dev,addrX);
|
||||
iot_epaper_send_command(dev,0x4f);
|
||||
iot_epaper_send_byte(dev,addrY);
|
||||
iot_epaper_send_byte(dev,addrY1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw a picture with a bit map
|
||||
*/
|
||||
void iot_drawBitmapBM(epaper_handle_t dev, const uint8_t *bitmap, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color, int16_t mode)
|
||||
{
|
||||
uint16_t inverse_color = (color != GxEPD_WHITE) ? GxEPD_WHITE : GxEPD_BLACK;
|
||||
uint16_t fg_color = (mode & bm_invert) ? inverse_color : color;
|
||||
uint16_t bg_color = (mode & bm_invert) ? color : inverse_color;
|
||||
int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
|
||||
uint8_t byte = 0;
|
||||
if (mode & bm_transparent)
|
||||
{
|
||||
for (uint16_t j = 0; j < h; j++)
|
||||
{
|
||||
for (uint16_t i = 0; i < w; i++ )
|
||||
{
|
||||
if (i & 7) byte <<= 1;
|
||||
else
|
||||
{
|
||||
byte = bitmap[j * byteWidth + i / 8];
|
||||
}
|
||||
// transparent mode
|
||||
if (!(byte & 0x80))
|
||||
{
|
||||
uint16_t xd = x + i;
|
||||
uint16_t yd = y + j;
|
||||
if (mode & bm_flip_x) xd = x + w - i;
|
||||
if (mode & bm_flip_y) yd = y + h - j;
|
||||
iot_drawPixel(dev, xd, yd, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint16_t j = 0; j < h; j++)
|
||||
{
|
||||
for (uint16_t i = 0; i < w; i++ )
|
||||
{
|
||||
if (i & 7) byte <<= 1;
|
||||
else
|
||||
{
|
||||
byte = bitmap[j * byteWidth + i / 8];
|
||||
}
|
||||
// keep using overwrite mode
|
||||
uint16_t pixelcolor = (byte & 0x80) ? fg_color : bg_color;
|
||||
uint16_t xd = x + i;
|
||||
uint16_t yd = y + j;
|
||||
if (mode & bm_flip_x) xd = x + w - i;
|
||||
if (mode & bm_flip_y) yd = y + h - j;
|
||||
iot_drawPixel(dev, xd, yd, pixelcolor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief InitDisplay
|
||||
*/
|
||||
void iot_InitDisplay(epaper_handle_t dev, uint8_t em)
|
||||
{
|
||||
iot_epaper_send_command(dev,0x12); //SWRESET
|
||||
esp_rom_delay_us(10000);
|
||||
iot_epaper_send_command(dev,0x01); //Driver output control
|
||||
iot_epaper_send_byte(dev,0x27);
|
||||
iot_epaper_send_byte(dev,0x01);
|
||||
iot_epaper_send_byte(dev,0x00);
|
||||
iot_epaper_send_command(dev,0x3C); //BorderWavefrom
|
||||
iot_epaper_send_byte(dev,0x05);
|
||||
iot_epaper_send_command(dev,0x21); // Display update control
|
||||
iot_epaper_send_byte(dev,0x00);
|
||||
iot_epaper_send_byte(dev,0x80);
|
||||
iot_epaper_send_command(dev,0x18); //Read built-in temperature sensor
|
||||
iot_epaper_send_byte(dev,0x80);
|
||||
iot_setRamDataEntryMode(dev, em);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update part of the display
|
||||
*/
|
||||
void iot_Update_Part(epaper_handle_t dev)
|
||||
{
|
||||
iot_epaper_send_command(dev,0x22);
|
||||
iot_epaper_send_byte(dev,0xcc);
|
||||
iot_epaper_send_command(dev,0x20);
|
||||
iot_epaper_wait_idle(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update full of the display
|
||||
*/
|
||||
void iot_Update_Full(epaper_handle_t dev)
|
||||
{
|
||||
iot_epaper_send_command(dev,0x22);
|
||||
iot_epaper_send_byte(dev,0xf7); // disable analog (powerOff() here)
|
||||
iot_epaper_send_command(dev,0x20);
|
||||
iot_epaper_wait_idle(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init for full update the display
|
||||
*/
|
||||
void iot_Init_Full(epaper_handle_t dev,uint8_t em)
|
||||
{
|
||||
iot_InitDisplay(dev, em);
|
||||
//iot_PowerOn(dev); //bug here?
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init_Part
|
||||
*/
|
||||
void iot_Init_Part(epaper_handle_t dev,uint8_t em)
|
||||
{
|
||||
iot_InitDisplay(dev,em);
|
||||
iot_epaper_send_command(dev, 0x32);
|
||||
for (uint16_t i = 0; i < sizeof(lut_partial); i++)
|
||||
{
|
||||
iot_epaper_send_byte(dev,pgm_read_byte(&lut_partial[i]));
|
||||
}
|
||||
//iot_PowerOn(dev); //bug here?
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw a pixel of the display
|
||||
*/
|
||||
void iot_drawPixel(epaper_handle_t dev, int16_t x, int16_t y, uint16_t color)
|
||||
{
|
||||
y = y + 6; //avoid can't write pixel
|
||||
if ((x < 0) || (x >= 250) || (y < 0) || (y >= 128)) return;
|
||||
uint16_t t;
|
||||
switch (iot_epaper_get_rotate(dev))
|
||||
{
|
||||
case 1:
|
||||
t = x;
|
||||
x = y;
|
||||
y = t;
|
||||
x = GxDEPG0213BN_WIDTH - x - 1;
|
||||
break;
|
||||
case 2:
|
||||
x = GxDEPG0213BN_WIDTH - x - 1;
|
||||
y = GxDEPG0213BN_HEIGHT - y - 1;
|
||||
break;
|
||||
case 3:
|
||||
t = x;
|
||||
x = y;
|
||||
y = t;
|
||||
y = GxDEPG0213BN_HEIGHT - y - 1;
|
||||
break;
|
||||
}
|
||||
// check rotation, move pixel around if necessary
|
||||
uint16_t i = x / 8 + y * GxDEPG0213BN_WIDTH / 8;
|
||||
if (iot_current_page < 1)
|
||||
{
|
||||
if (i >= sizeof(_buffer)) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
y -= iot_current_page * GxDEPG0213BN_PAGE_HEIGHT;
|
||||
if ((y < 0) || (y >= GxDEPG0213BN_PAGE_HEIGHT)) return;
|
||||
i = x / 8 + y * GxDEPG0213BN_WIDTH / 8;
|
||||
}
|
||||
|
||||
if (!color)
|
||||
_buffer[i] = (_buffer[i] | (1 << (7 - x % 8)));
|
||||
else
|
||||
_buffer[i] = (_buffer[i] & (0xFF ^ (1 << (7 - x % 8))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn on the display's power
|
||||
*/
|
||||
void iot_PowerOn(epaper_handle_t dev)
|
||||
{
|
||||
if (!iot_power_is_on)
|
||||
{
|
||||
iot_epaper_send_command(dev,(0x22));
|
||||
iot_epaper_send_byte(dev,(0xc0));
|
||||
iot_epaper_send_command(dev,(0x20));
|
||||
iot_epaper_wait_idle(dev);
|
||||
iot_power_is_on = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn off the display's power
|
||||
*/
|
||||
void iot_PowerOff(epaper_handle_t dev)
|
||||
{
|
||||
if (iot_power_is_on)
|
||||
{
|
||||
iot_epaper_send_command(dev,(0x22));
|
||||
iot_epaper_send_byte(dev,(0x83));
|
||||
iot_epaper_send_command(dev,(0x20));
|
||||
iot_epaper_wait_idle(dev);
|
||||
iot_power_is_on = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update part of the display
|
||||
*/
|
||||
void iot_epaper_updateWindow(epaper_handle_t dev,uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool using_rotation)
|
||||
{
|
||||
if (using_rotation) iot_rotate(&x, &y, &w, &h);
|
||||
if (x >= GxDEPG0213BN_WIDTH) return;
|
||||
if (y >= GxDEPG0213BN_HEIGHT) return;
|
||||
uint16_t xe = gx_uint16_min(GxDEPG0213BN_WIDTH, x + w) - 1;
|
||||
uint16_t ye = gx_uint16_min(GxDEPG0213BN_HEIGHT, y + h) - 1;
|
||||
uint16_t xs_d8 = x / 8;
|
||||
uint16_t xe_d8 = xe / 8;
|
||||
iot_Init_Part(dev, 0x03);
|
||||
|
||||
iot_SetRamArea(dev, xs_d8, xe_d8, y % 256, y / 256, ye % 256, ye / 256); // X-source area,Y-gate area
|
||||
iot_SetRamPointer(dev, xs_d8, y % 256, y / 256); // set ram
|
||||
iot_epaper_wait_idle(dev); //should exist?
|
||||
iot_epaper_send_command(dev,0x24);
|
||||
for (uint16_t y1 = y; y1 <= ye; y1++)
|
||||
{
|
||||
for (uint16_t x1 = xs_d8; x1 <= xe_d8; x1++)
|
||||
{
|
||||
uint16_t idx = y1 * (GxDEPG0213BN_WIDTH / 8) + x1;
|
||||
uint8_t data = (idx < sizeof(_buffer)) ? _buffer[idx] : 0x00;
|
||||
iot_epaper_send_byte(dev,~data);
|
||||
}
|
||||
}
|
||||
iot_Update_Part(dev);
|
||||
esp_rom_delay_us(300000);
|
||||
|
||||
// update previous buffer
|
||||
iot_SetRamArea(dev, xs_d8, xe_d8, y % 256, y / 256, ye % 256, ye / 256); // X-source area,Y-gate area
|
||||
iot_SetRamPointer(dev,xs_d8, y % 256, y / 256); // set ram
|
||||
iot_epaper_wait_idle(dev);
|
||||
iot_epaper_send_command(dev,(0x26));
|
||||
for (uint16_t y1 = y; y1 <= ye; y1++)
|
||||
{
|
||||
for (uint16_t x1 = xs_d8; x1 <= xe_d8; x1++)
|
||||
{
|
||||
uint16_t idx = y1 * (GxDEPG0213BN_WIDTH / 8) + x1;
|
||||
uint8_t data = (idx < sizeof(_buffer)) ? _buffer[idx] : 0x00;
|
||||
iot_epaper_send_byte(dev,(~data));
|
||||
}
|
||||
}
|
||||
esp_rom_delay_us(300000);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update full of the display
|
||||
*/
|
||||
void iot_epaper_update(epaper_handle_t dev)
|
||||
{
|
||||
//iot_epaper_reset(dev);
|
||||
|
||||
iot_Init_Full(dev,0x03);
|
||||
|
||||
//update
|
||||
iot_epaper_send_command(dev,0x24);
|
||||
for (uint16_t y = 0; y < GxDEPG0213BN_HEIGHT; y++)
|
||||
{
|
||||
for (uint16_t x = 0; x < GxDEPG0213BN_WIDTH / 8; x++)
|
||||
{
|
||||
uint16_t idx = y * (GxDEPG0213BN_WIDTH / 8) + x;
|
||||
uint8_t data = (idx < sizeof(_buffer)) ? _buffer[idx] : 0x00;
|
||||
iot_epaper_send_byte(dev,~data);
|
||||
}
|
||||
}
|
||||
iot_epaper_send_command(dev,0x26); // both buffers same for full b/w
|
||||
for (uint16_t y = 0; y < GxDEPG0213BN_HEIGHT; y++)
|
||||
{
|
||||
for (uint16_t x = 0; x < GxDEPG0213BN_WIDTH / 8; x++)
|
||||
{
|
||||
uint16_t idx = y * (GxDEPG0213BN_WIDTH / 8) + x;
|
||||
uint8_t data = (idx < sizeof(_buffer)) ? _buffer[idx] : 0x00;
|
||||
iot_epaper_send_byte(dev,~data);
|
||||
}
|
||||
}
|
||||
//update_full
|
||||
iot_Update_Full(dev);
|
||||
|
||||
//power off
|
||||
iot_PowerOff(dev);
|
||||
//iot_current_page = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief reset device
|
||||
*/
|
||||
void iot_epaper_reset(epaper_handle_t dev)
|
||||
{
|
||||
epaper_dev_t* device = (epaper_dev_t*) dev;
|
||||
xSemaphoreTakeRecursive(device->spi_mux, portMAX_DELAY);
|
||||
esp_rom_delay_us(20000);
|
||||
gpio_set_level((gpio_num_t) device->pin.reset_pin, 0); //module reset
|
||||
esp_rom_delay_us(20000);
|
||||
gpio_set_level((gpio_num_t) device->pin.reset_pin, 1);
|
||||
esp_rom_delay_us(200000);
|
||||
iot_epaper_wait_idle(dev);
|
||||
xSemaphoreGiveRecursive(device->spi_mux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exchange data in preparation for the screen rotation.
|
||||
*/
|
||||
void iot_rotate(uint16_t* x, uint16_t* y, uint16_t* w, uint16_t* h)
|
||||
{
|
||||
uint16_t t = *x;
|
||||
*x = *y;
|
||||
*y = t;
|
||||
//swap(x, y);
|
||||
t = *w;
|
||||
*w = *h;
|
||||
*h = t;
|
||||
//swap(w, h);
|
||||
*x = GxDEPG0213BN_WIDTH - *x - *w;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EraseDisplay(Not tested yet.)
|
||||
*/
|
||||
void iot_eraseDisplay(epaper_handle_t dev, bool using_partial_update)
|
||||
{
|
||||
if (iot_current_page != -1) return;
|
||||
if (using_partial_update)
|
||||
{
|
||||
iot_using_partial_mode = true; // remember
|
||||
iot_Init_Part(dev, 0x01);
|
||||
iot_epaper_send_command(dev,(0x24));
|
||||
for (uint32_t i = 0; i < 4000; i++)
|
||||
{
|
||||
iot_epaper_send_byte(dev,(0xFF));
|
||||
}
|
||||
iot_Update_Part(dev);
|
||||
esp_rom_delay_us(300000);
|
||||
// update previous buffer
|
||||
iot_epaper_send_command(dev,(0x26));
|
||||
for (uint32_t i = 0; i < 4000; i++)
|
||||
{
|
||||
iot_epaper_send_byte(dev,(0xFF));
|
||||
}
|
||||
esp_rom_delay_us(300000);
|
||||
}
|
||||
else
|
||||
{
|
||||
iot_using_partial_mode = false; // remember
|
||||
iot_Init_Full(dev,0x01);
|
||||
iot_epaper_send_command(dev,(0x24));
|
||||
for (uint32_t i = 0; i < 4000; i++)
|
||||
{
|
||||
iot_epaper_send_byte(dev,(0xFF));
|
||||
}
|
||||
iot_epaper_send_command(dev,(0x26)); // both buffers same for full b/w
|
||||
for (uint32_t i = 0; i < 4000; i++)
|
||||
{
|
||||
iot_epaper_send_byte(dev,0x00);
|
||||
}
|
||||
iot_Update_Full(dev);
|
||||
iot_PowerOff(dev);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,508 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _IOT_E_PAPER_H_
|
||||
#define _IOT_E_PAPER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
const uint8_t *font_table;
|
||||
} epaper_font_t;
|
||||
|
||||
#define BLACK_COLORED 0
|
||||
#define RED_COLORED 1
|
||||
#define UNCOLORED 2
|
||||
|
||||
// epd2in7 commands
|
||||
#define E_PAPER_PANEL_SETTING 0x00
|
||||
#define E_PAPER_POWER_SETTING 0x01
|
||||
#define E_PAPER_POWER_OFF 0x02
|
||||
#define E_PAPER_POWER_OFF_SEQUENCE_SETTING 0x03
|
||||
#define E_PAPER_POWER_ON 0x04
|
||||
#define E_PAPER_POWER_ON_MEASURE 0x05
|
||||
#define E_PAPER_BOOSTER_SOFT_START 0x06
|
||||
#define E_PAPER_DEEP_SLEEP 0x07
|
||||
#define E_PAPER_DATA_START_TRANSMISSION_1 0x10
|
||||
#define E_PAPER_DATA_STOP 0x11
|
||||
#define E_PAPER_DISPLAY_REFRESH 0x12
|
||||
#define E_PAPER_DATA_START_TRANSMISSION_2 0x13
|
||||
#define E_PAPER_PARTIAL_DATA_START_TRANSMISSION_1 0x14
|
||||
#define E_PAPER_PARTIAL_DATA_START_TRANSMISSION_2 0x15
|
||||
#define E_PAPER_PARTIAL_DISPLAY_REFRESH 0x16
|
||||
#define E_PAPER_LUT_FOR_VCOM 0x20
|
||||
#define E_PAPER_LUT_WHITE_TO_WHITE 0x21
|
||||
#define E_PAPER_LUT_BLACK_TO_WHITE 0x22
|
||||
#define E_PAPER_LUT_WHITE_TO_BLACK 0x23
|
||||
#define E_PAPER_LUT_BLACK_TO_BLACK 0x24
|
||||
#define E_PAPER_PLL_CONTROL 0x30
|
||||
#define E_PAPER_TEMPERATURE_SENSOR_COMMAND 0x40
|
||||
#define E_PAPER_TEMPERATURE_SENSOR_CALIBRATION 0x41
|
||||
#define E_PAPER_TEMPERATURE_SENSOR_WRITE 0x42
|
||||
#define E_PAPER_TEMPERATURE_SENSOR_READ 0x43
|
||||
#define E_PAPER_VCOM_AND_DATA_INTERVAL_SETTING 0x50
|
||||
#define E_PAPER_LOW_POWER_DETECTION 0x51
|
||||
#define E_PAPER_TCON_SETTING 0x60
|
||||
#define E_PAPER_TCON_RESOLUTION 0x61
|
||||
#define E_PAPER_SOURCE_AND_GATE_START_SETTING 0x62
|
||||
#define E_PAPER_GET_STATUS 0x71
|
||||
#define E_PAPER_AUTO_MEASURE_VCOM 0x80
|
||||
#define E_PAPER_VCOM_VALUE 0x81
|
||||
#define E_PAPER_VCM_DC_SETTING_REGISTER 0x82
|
||||
#define E_PAPER_PROGRAM_MODE 0xA0
|
||||
#define E_PAPER_ACTIVE_PROGRAM 0xA1
|
||||
#define E_PAPER_READ_OTP_DATA 0xA2
|
||||
|
||||
#define GxDEPG0213BN_X_PIXELS 128
|
||||
#define GxDEPG0213BN_Y_PIXELS 250
|
||||
|
||||
#define GxDEPG0213BN_WIDTH GxDEPG0213BN_X_PIXELS
|
||||
#define GxDEPG0213BN_HEIGHT GxDEPG0213BN_Y_PIXELS
|
||||
|
||||
#define GxDEPG0213BN_PAGES 4
|
||||
|
||||
#define GxDEPG0213BN_PAGE_HEIGHT (GxDEPG0213BN_HEIGHT / GxDEPG0213BN_PAGES)
|
||||
#define GxDEPG0213BN_PAGE_SIZE (GxDEPG0213BN_BUFFER_SIZE / GxDEPG0213BN_PAGES)
|
||||
|
||||
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
||||
|
||||
#define GxEPD_WHITE 0xFFFF
|
||||
#define GxEPD_BLACK 0x0000
|
||||
|
||||
enum bm_mode //BM_ModeSet
|
||||
{
|
||||
bm_normal = 0,
|
||||
bm_default = 1, // for use for BitmapExamples
|
||||
// these potentially can be combined
|
||||
bm_invert = (1 << 1),
|
||||
bm_flip_x = (1 << 2),
|
||||
bm_flip_y = (1 << 3),
|
||||
bm_r90 = (1 << 4),
|
||||
bm_r180 = (1 << 5),
|
||||
bm_r270 = bm_r90 | bm_r180,
|
||||
bm_partial_update = (1 << 6),
|
||||
bm_invert_red = (1 << 7),
|
||||
bm_transparent = (1 << 8)
|
||||
};
|
||||
|
||||
/* Paint properties */
|
||||
typedef struct {
|
||||
uint8_t Rotation;
|
||||
int width;
|
||||
int height;
|
||||
} epaper_paint_t;
|
||||
|
||||
/* EPD properties */
|
||||
typedef struct {
|
||||
int reset_pin;
|
||||
int dc_pin;
|
||||
int cs_pin;
|
||||
int busy_pin;
|
||||
int mosi_pin;
|
||||
int miso_pin;
|
||||
int sck_pin;
|
||||
|
||||
uint8_t rst_active_level;
|
||||
uint8_t dc_lev_data;
|
||||
uint8_t dc_lev_cmd;
|
||||
|
||||
int clk_freq_hz;
|
||||
spi_host_device_t spi_host;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
bool color_inv;
|
||||
} epaper_conf_t;
|
||||
|
||||
typedef void* epaper_handle_t; /*handle of epaper*/
|
||||
|
||||
/**
|
||||
* @brief Create and init epaper and return a epaper handle
|
||||
*
|
||||
* @param bus handle of spi device
|
||||
* @param epconf configure struct for epaper device
|
||||
*
|
||||
* @return
|
||||
* - handle of epaper
|
||||
*/
|
||||
epaper_handle_t iot_epaper_create(spi_device_handle_t bus, epaper_conf_t * epconf);
|
||||
|
||||
/**
|
||||
* @brief delete epaper handle_t
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param del_bus whether to delete spi bus
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL Fail
|
||||
*/
|
||||
esp_err_t iot_epaper_delete(epaper_handle_t dev, bool del_bus);
|
||||
|
||||
/**
|
||||
* @brief clear display frame buffer
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param colored to set display color
|
||||
*/
|
||||
void iot_epaper_clean_paint(epaper_handle_t dev, int colored);
|
||||
|
||||
/**
|
||||
* @brief get paint width
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
*
|
||||
* @return
|
||||
* - paint width
|
||||
*/
|
||||
int iot_epaper_get_width(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief set paint width
|
||||
* @param dev object handle of epaper
|
||||
* @param width paint width
|
||||
*/
|
||||
void iot_epaper_set_width(epaper_handle_t dev, int width);
|
||||
|
||||
/**
|
||||
* @brief get paint height
|
||||
* @param dev object handle of epaper
|
||||
* @return
|
||||
* - paint height
|
||||
*/
|
||||
int iot_epaper_get_height(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief set paint height
|
||||
* @param dev object handle of epaper
|
||||
* @param paint height
|
||||
*/
|
||||
void iot_epaper_set_height(epaper_handle_t dev, int height);
|
||||
|
||||
/**
|
||||
* @brief get paint rotate
|
||||
* @param dev object handle of epaper
|
||||
* @return
|
||||
* - current rotation
|
||||
*/
|
||||
int iot_epaper_get_rotate(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief set paint rotate
|
||||
* @param dev object handle of epaper
|
||||
* @param rotation
|
||||
*/
|
||||
void iot_epaper_set_rotate(epaper_handle_t dev, int rotate);
|
||||
|
||||
/**
|
||||
* @brief get display data
|
||||
* @param dev object handle of epaper
|
||||
* @return
|
||||
* - Pointer to display data
|
||||
*/
|
||||
unsigned char* iot_epaper_get_image(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief draw string start on point(x,y) and save on display data array,
|
||||
* screen will display when call iot_epaper_display_frame function.
|
||||
* @param dev object handle of epaper
|
||||
* @param x poing (x)
|
||||
* @param y poing (y)
|
||||
* @param text display string
|
||||
* @param font Font style
|
||||
* @param colored display color
|
||||
*/
|
||||
void iot_epaper_draw_string(epaper_handle_t dev, int x, int y, const char* text,
|
||||
epaper_font_t* font, int colored);
|
||||
|
||||
/**
|
||||
* @brief draw char and save on display data array,
|
||||
* screen will display when call iot_epaper_display_frame function.
|
||||
* @param dev object handle of epaper
|
||||
* @param x poing (x)
|
||||
* @param y poing (y)
|
||||
* @param ascii_char display char
|
||||
* @param font font style
|
||||
* @param colored display color
|
||||
*/
|
||||
void iot_epaper_draw_char(epaper_handle_t dev, int x, int y, char ascii_char,
|
||||
epaper_font_t* font, int colored);
|
||||
|
||||
/**
|
||||
* @brief draw line start on point(x0,y0) end on point(x1,y1) and save on display data array,
|
||||
* screen will display when call iot_epaper_display_frame function.
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param x0 poing (x0)
|
||||
* @param y0 poing (y0)
|
||||
* @param x1 poing (x1)
|
||||
* @param y1 poing (y1)
|
||||
* @param colored display color
|
||||
*/
|
||||
void iot_epaper_draw_line(epaper_handle_t dev, int x0, int y0, int x1, int y1,
|
||||
int colored);
|
||||
|
||||
/**
|
||||
* @brief draw horizontal line start on point(x,y) and save on display data array,
|
||||
* screen will display when call iot_epaper_display_frame function.
|
||||
* @param dev object handle of epaper
|
||||
* @param x poing (x)
|
||||
* @param y poing (y)
|
||||
* @param width line width
|
||||
* @param colored display color
|
||||
*/
|
||||
void iot_epaper_draw_horizontal_line(epaper_handle_t dev, int x, int y,
|
||||
int width, int colored);
|
||||
|
||||
/**
|
||||
* @brief draw vertical line start on point(x,y) and save on display data array,
|
||||
* screen will display when call iot_epaper_display_frame function.
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param x poing (x)
|
||||
* @param y poing (y)
|
||||
* @param line height
|
||||
* @param display color
|
||||
*/
|
||||
void iot_epaper_draw_vertical_line(epaper_handle_t dev, int x, int y,
|
||||
int height, int colored);
|
||||
|
||||
/**
|
||||
* @brief draw rectangle point(x0,y0) (x1,y1) and save on display data array,
|
||||
* screen will display when call iot_epaper_display_frame function.
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param x0 point(x0,y0)
|
||||
* @param y0 point(x0,y0)
|
||||
* @param x1 point(x1,y1)
|
||||
* @param y1 point(x1,y1)
|
||||
* @param colored display color
|
||||
*/
|
||||
void iot_epaper_draw_rectangle(epaper_handle_t dev, int x0, int y0, int x1,
|
||||
int y1, int colored);
|
||||
|
||||
/**
|
||||
* @brief draw fill rectangle point(x0,y0) (x1,y1) and save on display data array,
|
||||
* screen will display when call iot_epaper_display_frame function.
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param x0 point(x0,y0)
|
||||
* @param y0 point(x0,y0)
|
||||
* @param x1 point(x1,y1)
|
||||
* @param y1 point(x1,y1)
|
||||
* @param colored display color
|
||||
*/
|
||||
void iot_epaper_draw_filled_rectangle(epaper_handle_t dev, int x0, int y0,
|
||||
int x1, int y1, int colored);
|
||||
|
||||
/**
|
||||
* @brief draw a circle at point(x,y) and save on display data array,
|
||||
* screen will display when call iot_epaper_display_frame function.
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param x point(x,y)
|
||||
* @param y point(x,y)
|
||||
* @param colored display color
|
||||
*/
|
||||
void iot_epaper_draw_circle(epaper_handle_t dev, int x, int y, int radius,
|
||||
int colored);
|
||||
|
||||
/**
|
||||
* @brief draw a fill circle at point(x,y) and save on display data array,
|
||||
* screen will display when call iot_epaper_display_frame function.
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param x point(x,y)
|
||||
* @param y point(x,y)
|
||||
* @param radius radius of the circle
|
||||
* @param colored display color
|
||||
*/
|
||||
void iot_epaper_draw_filled_circle(epaper_handle_t dev, int x, int y,
|
||||
int radius, int colored);
|
||||
|
||||
/**
|
||||
* @brief wait until idle
|
||||
* @param dev object handle of epaper
|
||||
*/
|
||||
void iot_epaper_wait_idle(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief reset device
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
*/
|
||||
void iot_epaper_reset(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief init device hardware
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
*/
|
||||
void iot_epaper_epd_init(epaper_handle_t dev, uint8_t Data);
|
||||
|
||||
/**
|
||||
* @brief setRamDataEntryMode
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param em command
|
||||
*/
|
||||
void iot_setRamDataEntryMode(epaper_handle_t dev, uint8_t em);
|
||||
|
||||
/**
|
||||
* @brief SetRamArea
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
*/
|
||||
void iot_SetRamArea(epaper_handle_t dev, uint8_t Xstart, uint8_t Xend, uint8_t Ystart, uint8_t Ystart1, uint8_t Yend, uint8_t Yend1);
|
||||
|
||||
/**
|
||||
* @brief SetRamPointer
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
*/
|
||||
void iot_SetRamPointer(epaper_handle_t dev, uint8_t addrX, uint8_t addrY, uint8_t addrY1);
|
||||
|
||||
/**
|
||||
* @brief Draw a picture with a bit map
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param bitmap a bitmap object
|
||||
* @param x point(x,y)
|
||||
* @param y point(x,y)
|
||||
* @param w bitmap_width
|
||||
* @param h bitmap_hight
|
||||
* @param color fill_in_color
|
||||
* @param mode select roation mode
|
||||
*/
|
||||
void iot_drawBitmapBM(epaper_handle_t dev, const uint8_t *bitmap, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color, int16_t mode);
|
||||
|
||||
/**
|
||||
* @brief Init_Part
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param em commad
|
||||
*/
|
||||
void iot_Init_Part(epaper_handle_t dev,uint8_t em);
|
||||
|
||||
/**
|
||||
* @brief InitDisplay
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param em mode select
|
||||
*/
|
||||
void iot_InitDisplay(epaper_handle_t dev, uint8_t em);
|
||||
|
||||
/**
|
||||
* @brief Update part of the display
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
*/
|
||||
void iot_Update_Part(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief Init for full update the display
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param em mode select
|
||||
*/
|
||||
void iot_Init_Full(epaper_handle_t dev,uint8_t em);
|
||||
|
||||
/**
|
||||
* @brief Update full of the display
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
*/
|
||||
void iot_Update_Full(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief Update part of the display
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param x point(x,y)
|
||||
* @param y point(x,y)
|
||||
* @param w bitmap_width
|
||||
* @param h bitmap_hight
|
||||
* @param using_rotation choose to use rotation
|
||||
*/
|
||||
void iot_epaper_updateWindow(epaper_handle_t dev,uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool using_rotation);
|
||||
|
||||
/**
|
||||
* @brief Draw a pixel of the display
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param x point(x,y)
|
||||
* @param y point(x,y)
|
||||
* @param color fill_in_color
|
||||
*/
|
||||
void iot_drawPixel(epaper_handle_t dev, int16_t x, int16_t y, uint16_t color);
|
||||
|
||||
/**
|
||||
* @brief Turn on the display's power
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
*/
|
||||
void iot_PowerOn(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief Turn off the display's power
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
*/
|
||||
void iot_PowerOff(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief Update full of the display
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
*/
|
||||
void iot_epaper_update(epaper_handle_t dev);
|
||||
|
||||
/**
|
||||
* @brief Exchange data in preparation for the screen rotation.
|
||||
*
|
||||
* @param x point(x,y)
|
||||
* @param y point(x,y)
|
||||
* @param w bitmap_width
|
||||
* @param h bitmap_hight
|
||||
*/
|
||||
void iot_rotate(uint16_t* x, uint16_t* y, uint16_t* w, uint16_t* h);
|
||||
|
||||
/**
|
||||
* @brief EraseDisplay(Not tested yet.)
|
||||
*
|
||||
* @param dev object handle of epaper
|
||||
* @param using_partial_update choose to use partial_update
|
||||
*/
|
||||
void iot_eraseDisplay(epaper_handle_t dev, bool using_partial_update);
|
||||
|
||||
/**
|
||||
* @brief Find a smaller data
|
||||
*
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
static inline uint16_t gx_uint16_min(uint16_t a, uint16_t b) {return (a < b ? a : b);};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,636 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _IOT_EPAPER_FONTS_H_
|
||||
#define _IOT_EPAPER_FONTS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include "epaper.h"
|
||||
|
||||
extern epaper_font_t epaper_font_24;
|
||||
extern epaper_font_t epaper_font_20;
|
||||
extern epaper_font_t epaper_font_16;
|
||||
extern epaper_font_t epaper_font_12;
|
||||
extern epaper_font_t epaper_font_8;
|
||||
extern epaper_font_t epaper_font_meslo_7;
|
||||
extern epaper_font_t epaper_font_meslo_8;
|
||||
extern epaper_font_t epaper_font_meslo_9;
|
||||
extern epaper_font_t epaper_font_meslo_10;
|
||||
extern epaper_font_t epaper_font_meslo_11;
|
||||
|
||||
const unsigned char espressif_logo[1968] = { /* 0X00,0X01,0X7B,0X00,0X7B,0X00, */
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X07,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F,0XFF,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3F,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X01,0XF0,0X00,0X00,0X07,0XFF,0XFF,0XFC,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X07,0XFF,0X00,0X00,0X01,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X0F,0XFF,0XF0,0X00,0X00,0X7F,0XFF,0XFF,0X80,0X00,0X00,0X00,
|
||||
0X00,0X00,0X18,0X00,0X3F,0XFF,0XFF,0X00,0X00,0X3F,0XFF,0XFF,0XE0,0X00,0X00,0X00,
|
||||
0X00,0X00,0X3C,0X00,0X7F,0XFF,0XFF,0XC0,0X00,0X0F,0XFF,0XFF,0XF0,0X00,0X00,0X00,
|
||||
0X00,0X00,0X7E,0X00,0XFF,0XFF,0XFF,0XF0,0X00,0X03,0XFF,0XFF,0XF8,0X00,0X00,0X00,
|
||||
0X00,0X00,0XFC,0X01,0XFF,0XFF,0XFF,0XFE,0X00,0X00,0XFF,0XFF,0XFC,0X00,0X00,0X00,
|
||||
0X00,0X01,0XF8,0X03,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X7F,0XFF,0XFF,0X00,0X00,0X00,
|
||||
0X00,0X03,0XF0,0X0F,0XFF,0XFF,0XFF,0XFF,0XE0,0X00,0X3F,0XFF,0XFF,0X80,0X00,0X00,
|
||||
0X00,0X03,0XE0,0X0F,0XFF,0XFF,0XFF,0XFF,0XF8,0X00,0X0F,0XFF,0XFF,0XC0,0X00,0X00,
|
||||
0X00,0X07,0XC0,0X0F,0XFF,0XFF,0XFF,0XFF,0XFE,0X00,0X07,0XFF,0XFF,0XE0,0X00,0X00,
|
||||
0X00,0X0F,0XC0,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X01,0XFF,0XFF,0XF0,0X00,0X00,
|
||||
0X00,0X0F,0X80,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XC0,0X00,0XFF,0XFF,0XF8,0X00,0X00,
|
||||
0X00,0X1F,0X00,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X7F,0XFF,0XF8,0X00,0X00,
|
||||
0X00,0X3E,0X00,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XF8,0X00,0X3F,0XFF,0XFC,0X00,0X00,
|
||||
0X00,0X3E,0X00,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFE,0X00,0X1F,0XFF,0XFE,0X00,0X00,
|
||||
0X00,0X7C,0X00,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X0F,0XFF,0XFF,0X00,0X00,
|
||||
0X00,0XF8,0X00,0X00,0X01,0XFF,0XFF,0XFF,0XFF,0XFF,0XC0,0X03,0XFF,0XFF,0X80,0X00,
|
||||
0X00,0XF8,0X00,0X00,0X00,0X0F,0XFF,0XFF,0XFF,0XFF,0XE0,0X01,0XFF,0XFF,0X80,0X00,
|
||||
0X01,0XF0,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0XFF,0XFF,0XC0,0X00,
|
||||
0X01,0XF0,0X00,0X00,0X00,0X00,0X1F,0XFF,0XFF,0XFF,0XF8,0X00,0X7F,0XFF,0XC0,0X00,
|
||||
0X03,0XE0,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFE,0X00,0X3F,0XFF,0XE0,0X00,
|
||||
0X03,0XE0,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X1F,0XFF,0XF0,0X00,
|
||||
0X03,0XC0,0X00,0X00,0X00,0X00,0X00,0X3F,0XFF,0XFF,0XFF,0X80,0X0F,0XFF,0XF0,0X00,
|
||||
0X07,0XC0,0X00,0X00,0X00,0X00,0X00,0X0F,0XFF,0XFF,0XFF,0XC0,0X0F,0XFF,0XF8,0X00,
|
||||
0X07,0X80,0X00,0X3F,0XFE,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XE0,0X07,0XFF,0XF8,0X00,
|
||||
0X07,0X80,0X01,0XFF,0XFF,0XF0,0X00,0X00,0XFF,0XFF,0XFF,0XF0,0X03,0XFF,0XFC,0X00,
|
||||
0X0F,0X80,0X07,0XFF,0XFF,0XFE,0X00,0X00,0X3F,0XFF,0XFF,0XF8,0X01,0XFF,0XFC,0X00,
|
||||
0X0F,0X00,0X0F,0XFF,0XFF,0XFF,0XC0,0X00,0X1F,0XFF,0XFF,0XFC,0X00,0XFF,0XFC,0X00,
|
||||
0X0F,0X00,0X3F,0XFF,0XFF,0XFF,0XF0,0X00,0X07,0XFF,0XFF,0XFE,0X00,0X7F,0XFE,0X00,
|
||||
0X1F,0X00,0X7F,0XFF,0XFF,0XFF,0XFC,0X00,0X03,0XFF,0XFF,0XFE,0X00,0X7F,0XFE,0X00,
|
||||
0X1E,0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X01,0XFF,0XFF,0XFF,0X00,0X3F,0XFF,0X00,
|
||||
0X1E,0X01,0XFF,0XFF,0XFF,0XFF,0XFF,0XE0,0X00,0XFF,0XFF,0XFF,0X80,0X1F,0XFF,0X00,
|
||||
0X3E,0X01,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X3F,0XFF,0XFF,0XC0,0X1F,0XFF,0X00,
|
||||
0X3E,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,0XFC,0X00,0X1F,0XFF,0XFF,0XE0,0X0F,0XFF,0X80,
|
||||
0X3C,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFE,0X00,0X0F,0XFF,0XFF,0XE0,0X07,0XFF,0X80,
|
||||
0X3C,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X07,0XFF,0XFF,0XF0,0X03,0XFF,0X80,
|
||||
0X7C,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XC0,0X03,0XFF,0XFF,0XF8,0X03,0XFF,0X80,
|
||||
0X7C,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XE0,0X01,0XFF,0XFF,0XF8,0X01,0XFF,0X80,
|
||||
0X7C,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF8,0X00,0XFF,0XFF,0XFC,0X01,0XFF,0XC0,
|
||||
0X78,0X1F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFC,0X00,0X7F,0XFF,0XFE,0X00,0XFF,0XC0,
|
||||
0X78,0X1F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFE,0X00,0X3F,0XFF,0XFF,0X00,0XFF,0XC0,
|
||||
0X78,0X1F,0XFF,0XFC,0X1F,0XFF,0XFF,0XFF,0XFF,0X00,0X1F,0XFF,0XFF,0X00,0X7F,0XC0,
|
||||
0X78,0X1F,0XFF,0XF8,0X00,0XFF,0XFF,0XFF,0XFF,0X80,0X0F,0XFF,0XFF,0X80,0X3F,0XC0,
|
||||
0X78,0X1F,0XFF,0XF0,0X00,0X1F,0XFF,0XFF,0XFF,0XC0,0X0F,0XFF,0XFF,0X80,0X3F,0XC0,
|
||||
0X78,0X1F,0XFF,0XF0,0X00,0X03,0XFF,0XFF,0XFF,0XE0,0X07,0XFF,0XFF,0XC0,0X1F,0XC0,
|
||||
0X78,0X1F,0XFF,0XF0,0X00,0X00,0XFF,0XFF,0XFF,0XF0,0X03,0XFF,0XFF,0XC0,0X1F,0XC0,
|
||||
0XF8,0X1F,0XFF,0XF0,0X00,0X00,0X3F,0XFF,0XFF,0XF0,0X01,0XFF,0XFF,0XE0,0X1F,0XE0,
|
||||
0XF8,0X1F,0XFF,0XF8,0X00,0X00,0X1F,0XFF,0XFF,0XF8,0X01,0XFF,0XFF,0XE0,0X0F,0XE0,
|
||||
0XF8,0X1F,0XFF,0XFC,0X00,0X00,0X07,0XFF,0XFF,0XFC,0X00,0XFF,0XFF,0XF0,0X0F,0XC0,
|
||||
0XF8,0X1F,0XFF,0XFF,0XE0,0X00,0X03,0XFF,0XFF,0XFE,0X00,0XFF,0XFF,0XF0,0X07,0XC0,
|
||||
0XF8,0X0F,0XFF,0XFF,0XFE,0X00,0X00,0XFF,0XFF,0XFF,0X00,0X7F,0XFF,0XF0,0X07,0XC0,
|
||||
0X78,0X0F,0XFF,0XFF,0XFF,0XC0,0X00,0X7F,0XFF,0XFF,0X00,0X3F,0XFF,0XF8,0X03,0XC0,
|
||||
0X78,0X0F,0XFF,0XFF,0XFF,0XF0,0X00,0X3F,0XFF,0XFF,0X80,0X3F,0XFF,0XFC,0X03,0XC0,
|
||||
0X78,0X07,0XFF,0XFF,0XFF,0XF8,0X00,0X1F,0XFF,0XFF,0XC0,0X1F,0XFF,0XFC,0X03,0XC0,
|
||||
0X78,0X07,0XFF,0XFF,0XFF,0XFF,0X00,0X0F,0XFF,0XFF,0XC0,0X1F,0XFF,0XFC,0X01,0X00,
|
||||
0X78,0X07,0XFF,0XFF,0XFF,0XFF,0X80,0X07,0XFF,0XFF,0XE0,0X0F,0XFF,0XFE,0X00,0X00,
|
||||
0X78,0X03,0XFF,0XFF,0XFF,0XFF,0XE0,0X03,0XFF,0XFF,0XE0,0X0F,0XFF,0XFE,0X00,0X00,
|
||||
0X78,0X01,0XFF,0XFF,0XFF,0XFF,0XE0,0X01,0XFF,0XFF,0XF0,0X07,0XFF,0XFF,0X00,0X00,
|
||||
0X7C,0X00,0XFF,0XFF,0XFF,0XFF,0XF8,0X00,0XFF,0XFF,0XF0,0X07,0XFF,0XFF,0X00,0X00,
|
||||
0X7C,0X00,0X7F,0XFF,0XFF,0XFF,0XFC,0X00,0XFF,0XFF,0XF8,0X03,0XFF,0XFF,0X00,0X00,
|
||||
0X3C,0X00,0X3F,0XFF,0XFF,0XFF,0XFE,0X00,0X7F,0XFF,0XF8,0X03,0XFF,0XFF,0X80,0X00,
|
||||
0X3C,0X00,0X1F,0XFF,0XFF,0XFF,0XFF,0X00,0X3F,0XFF,0XFC,0X03,0XFF,0XFF,0X80,0X00,
|
||||
0X3C,0X00,0X0F,0XFF,0XFF,0XFF,0XFF,0X80,0X1F,0XFF,0XFC,0X01,0XFF,0XFF,0X80,0X00,
|
||||
0X3E,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XC0,0X1F,0XFF,0XFE,0X01,0XFF,0XFF,0X80,0X00,
|
||||
0X1E,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0XE0,0X0F,0XFF,0XFE,0X01,0XFF,0XFF,0XC0,0X00,
|
||||
0X1E,0X00,0X00,0X1F,0XFF,0XFF,0XFF,0XE0,0X0F,0XFF,0XFE,0X00,0XFF,0XFF,0XC0,0X00,
|
||||
0X1E,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XF0,0X07,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X00,
|
||||
0X1F,0X00,0X00,0X00,0X0F,0XFF,0XFF,0XF0,0X07,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X00,
|
||||
0X0F,0X00,0X00,0X00,0X03,0XFF,0XFF,0XF8,0X03,0XFF,0XFF,0X00,0X7F,0XFF,0XE0,0X00,
|
||||
0X0F,0X00,0X00,0X00,0X01,0XFF,0XFF,0XF8,0X03,0XFF,0XFF,0X80,0X7F,0XFF,0XE0,0X00,
|
||||
0X0F,0X80,0X00,0X00,0X00,0X7F,0XFF,0XFC,0X01,0XFF,0XFF,0X80,0X7F,0XFF,0XE0,0X00,
|
||||
0X07,0X80,0X00,0X00,0X00,0X3F,0XFF,0XFC,0X01,0XFF,0XFF,0X80,0X7F,0XFF,0XE0,0X00,
|
||||
0X07,0XC0,0X00,0X00,0X00,0X1F,0XFF,0XFE,0X01,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X00,
|
||||
0X07,0XC0,0X00,0X00,0X00,0X0F,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XF0,0X00,
|
||||
0X03,0XC0,0X00,0X00,0X00,0X0F,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XF0,0X00,
|
||||
0X03,0XE0,0X00,0X00,0X00,0X07,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X00,
|
||||
0X01,0XE0,0X00,0X0F,0XF0,0X03,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XC0,0X00,
|
||||
0X01,0XF0,0X00,0X1F,0XF8,0X03,0XFF,0XFF,0X80,0X7F,0XFF,0XC0,0X1F,0XFF,0XC0,0X00,
|
||||
0X00,0XF0,0X00,0X3F,0XFC,0X01,0XFF,0XFF,0X80,0X7F,0XFF,0XE0,0X1F,0XFF,0X80,0X00,
|
||||
0X00,0XF8,0X00,0X7F,0XFE,0X01,0XFF,0XFF,0X80,0X7F,0XFF,0XE0,0X1F,0XFF,0X80,0X00,
|
||||
0X00,0X7C,0X00,0XFF,0XFF,0X01,0XFF,0XFF,0X80,0X7F,0XFF,0XE0,0X1F,0XFF,0X00,0X00,
|
||||
0X00,0X3C,0X00,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X7F,0XFF,0XE0,0X1F,0XFE,0X00,0X00,
|
||||
0X00,0X3E,0X00,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X1F,0XFE,0X00,0X00,
|
||||
0X00,0X1E,0X00,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X1F,0XFC,0X00,0X00,
|
||||
0X00,0X1F,0X00,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X1F,0XF8,0X00,0X00,
|
||||
0X00,0X0F,0X80,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X1F,0XF0,0X00,0X00,
|
||||
0X00,0X07,0XC0,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X1F,0XE0,0X00,0X00,
|
||||
0X00,0X07,0XC0,0X7F,0XFE,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X00,0X00,0X00,0X00,
|
||||
0X00,0X03,0XE0,0X7F,0XFC,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X00,0X00,0X00,0X00,
|
||||
0X00,0X01,0XF0,0X3F,0XF8,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0XF8,0X0F,0XF0,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X7C,0X07,0XE0,0X00,0XFF,0XFF,0XC0,0X3F,0XFF,0XE0,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X3E,0X00,0X00,0X00,0XFF,0XFF,0X80,0X7F,0XFF,0XE0,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X1F,0X00,0X00,0X01,0XFF,0XFF,0X80,0X7F,0XFF,0XE0,0X00,0X01,0X00,0X00,
|
||||
0X00,0X00,0X0F,0X80,0X00,0X01,0XFF,0XFF,0X80,0X7F,0XFF,0XE0,0X00,0X03,0X80,0X00,
|
||||
0X00,0X00,0X0F,0XC0,0X00,0X01,0XFF,0XFF,0X80,0X7F,0XFF,0XE0,0X00,0X07,0XC0,0X00,
|
||||
0X00,0X00,0X07,0XE0,0X00,0X03,0XFF,0XFF,0X80,0X7F,0XFF,0XC0,0X00,0X1F,0XC0,0X00,
|
||||
0X00,0X00,0X01,0XF8,0X00,0X03,0XFF,0XFF,0X80,0X7F,0XFF,0XC0,0X00,0X3F,0X80,0X00,
|
||||
0X00,0X00,0X00,0XFC,0X00,0X03,0XFF,0XFF,0X00,0XFF,0XFF,0XC0,0X00,0X7E,0X00,0X00,
|
||||
0X00,0X00,0X00,0X7E,0X00,0X00,0XFF,0XFF,0X00,0XFF,0XFF,0X80,0X00,0XFC,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0X80,0X00,0X3F,0XFF,0X00,0X07,0XFC,0X00,0X03,0XF8,0X00,0X00,
|
||||
0X00,0X00,0X00,0X0F,0XC0,0X00,0X1F,0XFE,0X00,0X01,0XF0,0X00,0X07,0XE0,0X00,0X00,
|
||||
0X00,0X00,0X00,0X07,0XF0,0X00,0X03,0XFE,0X00,0X00,0X00,0X00,0X1F,0XC0,0X00,0X00,
|
||||
0X00,0X00,0X00,0X03,0XFC,0X00,0X00,0X0C,0X00,0X00,0X00,0X00,0X7F,0X80,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XFE,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X3F,0X80,0X00,0X00,0X00,0X00,0X00,0X07,0XF8,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X1F,0XF0,0X00,0X00,0X00,0X00,0X00,0X1F,0XF0,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X07,0XFE,0X00,0X00,0X00,0X00,0X00,0XFF,0XC0,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X01,0XFF,0XC0,0X00,0X00,0X00,0X07,0XFF,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X3F,0XFC,0X00,0X00,0X00,0XFF,0XFC,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X0F,0XFF,0XF0,0X00,0X1F,0XFF,0XE0,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X01,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XFF,0XFF,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFE,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
};
|
||||
|
||||
const unsigned char matter_logo[3904] = { /* 0X00,0X01,0XFA,0X00,0X7A,0X00, */
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X07,0XE0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X01,0X00,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X47,0XF0,0X7C,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X4F,0XFC,0X1F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X8F,0XFF,0X0F,0X00,0X00,0XFF,0XE0,0XFF,0XC1,0XFF,0XC1,0XFF,0XC0,0X7F,0XE0,
|
||||
0XFF,0XE0,0XFF,0XC1,0XC1,0XFF,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X01,0X00,0XFF,0X87,0X80,0X00,0XFF,0XE1,0XFF,0XC3,0XFF,0XE1,0XFF,0XE0,0XFF,0XE1,
|
||||
0XFF,0XE1,0XFF,0XE3,0XC7,0XFF,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X01,0X00,0X1F,0XE3,0XC0,0X01,0XFF,0XE1,0XFF,0XC1,0XFF,0XF1,0XFF,0XF1,0XFF,0XE1,
|
||||
0XFF,0XE1,0XFF,0XE1,0XC7,0XFF,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X02,0X0C,0X07,0XF1,0XC0,0X01,0XC0,0X03,0XC0,0X01,0XC0,0X71,0XC0,0XF1,0XC0,0X03,
|
||||
0XC0,0X03,0XC0,0X01,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X02,0X3F,0XC1,0XF8,0XE0,0X01,0XC0,0X03,0X80,0X01,0XC0,0X71,0XC0,0X71,0XC0,0X03,
|
||||
0XC0,0X03,0X80,0X01,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X02,0X7F,0XF0,0XF8,0XE0,0X01,0XC0,0X03,0X80,0X01,0XC0,0X71,0XC0,0X71,0XC0,0X03,
|
||||
0X80,0X03,0X80,0X01,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0XFF,0XF8,0X7C,0X60,0X01,0XC0,0X03,0X80,0X03,0XC0,0X71,0XC0,0X71,0XC0,0X03,
|
||||
0X80,0X03,0X80,0X03,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0XFB,0XFC,0X3E,0X20,0X01,0XC0,0X03,0X80,0X01,0XC0,0X71,0XC0,0X71,0XC0,0X03,
|
||||
0XC0,0X03,0X80,0X01,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X04,0XF0,0X7F,0X1E,0X30,0X01,0XC0,0X03,0XC0,0X01,0XC0,0X71,0XC0,0X71,0XC0,0X03,
|
||||
0XC0,0X03,0XC0,0X01,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X04,0XF0,0X1F,0X9F,0X10,0X01,0XFF,0XC3,0XFF,0XC1,0XC0,0X71,0XC0,0XF1,0XFF,0XC1,
|
||||
0XFF,0XC1,0XFF,0XC1,0XC7,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X04,0XFF,0X0F,0X8F,0X10,0X01,0XFF,0XC1,0XFF,0XE3,0XFF,0XF1,0XFF,0XF1,0XFF,0XC1,
|
||||
0XFF,0XE1,0XFF,0XE3,0XC7,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X7F,0XC7,0XCF,0X80,0X01,0XFF,0XC0,0XFF,0XE1,0XFF,0XE1,0XFF,0XE1,0XFF,0XC0,
|
||||
0XFF,0XE0,0XFF,0XE1,0XC7,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X3F,0XE3,0XC7,0X80,0X01,0XC0,0X00,0X00,0XE1,0XFF,0XC1,0XFF,0XC1,0XC0,0X00,
|
||||
0X00,0XF0,0X00,0XE1,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X02,0X0F,0XE3,0XE7,0X80,0X01,0XC0,0X00,0X00,0XE1,0XC0,0X01,0XC1,0XE1,0XC0,0X00,
|
||||
0X00,0XF0,0X00,0XE1,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X02,0X01,0XF1,0XE3,0XC0,0X01,0XC0,0X00,0X00,0XE1,0XC0,0X01,0XC0,0XE1,0XC0,0X00,
|
||||
0X00,0XE0,0X00,0XE3,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0XF9,0XE3,0XC0,0X01,0XC0,0X00,0X00,0XE3,0XC0,0X01,0XC0,0XF1,0XC0,0X00,
|
||||
0X00,0XE0,0X00,0XE3,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X01,0X00,0X79,0XF3,0XC0,0X01,0XC0,0X00,0X00,0XE1,0XC0,0X01,0XC0,0X71,0XC0,0X00,
|
||||
0X00,0XF0,0X00,0XE1,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X0E,0X78,0XF3,0X80,0X01,0XC0,0X00,0X00,0XE1,0XC0,0X01,0XC0,0X71,0XC0,0X00,
|
||||
0X00,0XF0,0X00,0XE1,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X9E,0X78,0XF3,0X00,0X01,0XE0,0X00,0X01,0XE1,0XC0,0X01,0XC0,0X71,0XE0,0X00,
|
||||
0X00,0XF0,0X00,0XE1,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X4E,0X78,0XF0,0X00,0X01,0XFF,0XE3,0XFF,0XE1,0XC0,0X01,0XC0,0X79,0XFF,0XF3,
|
||||
0XFF,0XE3,0XFF,0XE1,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X20,0X78,0XF0,0X00,0X00,0XFF,0XE3,0XFF,0XC3,0XC0,0X01,0XC0,0X78,0XFF,0XF3,
|
||||
0XFF,0XC3,0XFF,0XC3,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X10,0X79,0XF0,0X80,0X00,0X00,0X21,0X00,0X00,0X00,0X00,0X00,0X10,0X01,0XE1,
|
||||
0X00,0X01,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X08,0X38,0X41,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X06,0X00,0X06,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X01,0X80,0X18,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X3F,0XC0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0E,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0E,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0E,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0E,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0E,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0E,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XC0,0X30,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0E,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XC0,0X30,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0X0E,
|
||||
0X10,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XC0,0X30,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X07,0XCE,
|
||||
0X7C,0X00,0X00,0X03,0X00,0XE0,0X00,0X70,0X00,0XC0,0X30,0X00,0XE0,0X00,0X60,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X07,0XFF,
|
||||
0XFC,0X00,0X00,0X0F,0XE3,0XF8,0X01,0XFC,0XC3,0XFF,0XFF,0X03,0XF8,0X01,0XE0,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XFF,
|
||||
0XF0,0X00,0X00,0X18,0X77,0X0C,0X03,0X06,0XC0,0XC0,0X30,0X06,0X0E,0X03,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X7F,
|
||||
0XC0,0X00,0X00,0X30,0X3C,0X06,0X06,0X03,0XC0,0XC0,0X30,0X0C,0X07,0X06,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X20,0X1C,0X02,0X0C,0X01,0XC0,0XC0,0X30,0X18,0X03,0X04,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X38,0X00,
|
||||
0X03,0X80,0X00,0X60,0X08,0X03,0X08,0X00,0XC0,0XC0,0X30,0X10,0X01,0X0C,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3E,0X00,
|
||||
0X0F,0X80,0X00,0X60,0X08,0X03,0X18,0X00,0XC0,0XC0,0X30,0X30,0X01,0X8C,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3F,0X00,
|
||||
0X1F,0X80,0X00,0X60,0X08,0X03,0X18,0X00,0XC0,0XC0,0X30,0X3F,0XFF,0X8C,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0X80,
|
||||
0X3E,0X00,0X00,0X60,0X08,0X03,0X18,0X00,0XC0,0XC0,0X30,0X30,0X00,0X0C,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X07,0X80,
|
||||
0X7C,0X00,0X00,0X60,0X08,0X03,0X08,0X00,0XC0,0XC0,0X30,0X30,0X00,0X0C,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XC0,
|
||||
0X78,0X00,0X00,0X60,0X08,0X03,0X0C,0X00,0XC0,0XC0,0X30,0X18,0X00,0X0C,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X07,0XE0,
|
||||
0XFC,0X00,0X00,0X60,0X08,0X03,0X0C,0X01,0XC0,0XC0,0X30,0X18,0X00,0X0C,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XE0,
|
||||
0XFF,0X00,0X00,0X60,0X08,0X03,0X07,0X03,0XC0,0XC0,0X30,0X0E,0X07,0X0C,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X7F,0XE0,
|
||||
0XFF,0XC0,0X00,0X60,0X08,0X03,0X03,0XFE,0XC0,0X7C,0X1F,0X07,0XFE,0X0C,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XFC,0XF1,
|
||||
0XE7,0XF0,0X00,0X20,0X08,0X03,0X00,0XF8,0XC0,0X38,0X0F,0X01,0XF8,0X04,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XF0,0XF1,
|
||||
0XE1,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XE0,0XF1,
|
||||
0XE0,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF1,
|
||||
0XE0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X71,
|
||||
0XC0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XC0,
|
||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XC0,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
};
|
||||
|
||||
const unsigned char matter_comminsion[3520] = { /* 0X00,0X01,0XFA,0X00,0X6E,0X00, */
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X38,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X38,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X38,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X38,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XFF,0XF9,0XFE,0X38,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X38,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X08,0X08,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XFF,0XF9,0XFE,0X38,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X38,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X08,0X08,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X38,0X00,0X39,0XC0,0X00,0XC0,0X00,0XC0,0X00,0X00,0X02,0X38,0X80,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X08,0X08,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X30,0X00,0X39,0XC0,0X00,0XC0,0X00,0XC0,0X00,0X00,0X0F,0XFB,0XE0,
|
||||
0X00,0X01,0XC0,0XE0,0X03,0XC4,0X3F,0XFF,0X00,0XE0,0X03,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X30,0X00,0X39,0XC0,0X00,0XC0,0X00,0XC0,0X00,0X00,0X07,0XFF,0XC0,
|
||||
0X00,0X07,0XF3,0XF8,0X0F,0XF4,0X3F,0XFF,0X83,0XF8,0X0F,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XFF,0XF8,0XC7,0XF8,0XC0,0X00,0X00,0X01,0XFF,0X00,
|
||||
0X00,0X0C,0X1E,0X0C,0X18,0X1C,0X08,0X08,0X06,0X0C,0X08,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XFF,0XF8,0XC7,0XF8,0XC0,0X00,0X00,0X00,0X18,0X00,
|
||||
0X00,0X08,0X0C,0X04,0X10,0X0C,0X08,0X08,0X08,0X06,0X18,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XFF,0XF8,0XC7,0XF8,0XC0,0X00,0X00,0X30,0X00,0X18,
|
||||
0X00,0X08,0X0C,0X06,0X30,0X0C,0X08,0X08,0X18,0X02,0X10,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XC6,0X38,0XC7,0XF8,0XC0,0X00,0X00,0X3C,0X00,0X38,
|
||||
0X00,0X08,0X0C,0X06,0X20,0X04,0X08,0X08,0X18,0X02,0X10,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XC6,0X38,0XC7,0XF8,0XC0,0X00,0X00,0X3E,0X00,0XF8,
|
||||
0X00,0X18,0X0C,0X06,0X20,0X04,0X08,0X08,0X1F,0XFF,0X10,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XC0,0X38,0XC7,0XF8,0XC0,0X00,0X00,0X0F,0X01,0XF0,
|
||||
0X00,0X18,0X0C,0X06,0X20,0X04,0X08,0X08,0X18,0X00,0X10,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XC0,0X38,0XC7,0XF8,0XC0,0X00,0X00,0X07,0X01,0XC0,
|
||||
0X00,0X18,0X0C,0X06,0X30,0X0C,0X08,0X08,0X18,0X00,0X10,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XC0,0X38,0XC7,0XF8,0XC0,0X00,0X00,0X0F,0X83,0XE0,
|
||||
0X00,0X18,0X0C,0X06,0X10,0X0C,0X08,0X08,0X0C,0X00,0X10,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X30,0X00,0X39,0XF9,0XC0,0XC0,0X00,0XC0,0X00,0X00,0X1F,0X83,0XF8,
|
||||
0X00,0X18,0X0C,0X06,0X18,0X1C,0X08,0X0C,0X06,0X06,0X10,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X30,0X00,0X39,0XF9,0XC0,0XC0,0X00,0XC0,0X00,0X00,0X7F,0XC7,0XFC,
|
||||
0X00,0X18,0X0C,0X06,0X0F,0XF4,0X0F,0X07,0X83,0XF8,0X10,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X38,0X00,0X39,0XF9,0XC0,0XC0,0X00,0XC0,0X00,0X01,0XF9,0XC7,0X3F,
|
||||
0X00,0X08,0X04,0X02,0X03,0XC0,0X00,0X00,0X80,0XE0,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XFF,0XF9,0XC6,0X38,0XFF,0XFF,0XC0,0X00,0X01,0XE1,0XC7,0X0F,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XFF,0XF9,0XC6,0X38,0XFF,0XFF,0XC0,0X00,0X00,0X81,0XC7,0X02,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X01,0XC7,0XF8,0X00,0X00,0X00,0X00,0X00,0X01,0XC7,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X01,0XC7,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X44,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X01,0XC7,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X38,0X06,0X3F,0XF9,0XC7,0XFF,0XC0,0XC0,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X38,0X06,0X3F,0XF9,0XC7,0XFF,0XC0,0XC0,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X39,0XDE,0X3F,0XF9,0XC7,0XFF,0XC0,0XC0,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X07,0XF9,0XC1,0XF9,0XF8,0XC7,0X07,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X07,0XF9,0XC1,0XF9,0XF8,0XC7,0X07,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XC1,0XFE,0X3F,0XC7,0XC7,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XC1,0XFE,0X3F,0XC7,0XC7,0XC7,0X00,0X00,0X00,0X00,0X60,0X30,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XE0,0X60,0X38,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XC1,0XFE,0X3F,0XC7,0XC7,0XC7,0X00,0X00,0X03,0XC1,0XF0,0XF8,
|
||||
0X0C,0X00,0X3F,0X83,0X0F,0XE0,0X01,0XF0,0XF8,0X7C,0X38,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X38,0X3E,0X00,0X3E,0X00,0X38,0X07,0XC0,0X00,0X00,0XC3,0X19,0X8C,
|
||||
0X1C,0X00,0X30,0X06,0X00,0X60,0X03,0X19,0X8C,0XC4,0X08,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X38,0X3E,0X00,0X3E,0X00,0X38,0X07,0XC0,0X00,0X00,0XC3,0X18,0X0C,
|
||||
0X34,0X00,0X30,0X04,0X00,0X40,0X02,0X19,0X04,0X86,0X08,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X38,0X3E,0X00,0X3E,0X00,0X38,0X07,0XC0,0X00,0X00,0XC0,0X18,0X0C,
|
||||
0X24,0X00,0X3E,0X0F,0X00,0XC0,0X03,0X19,0X04,0X8E,0X08,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XC6,0X3E,0X00,0X3F,0XFF,0X07,0XC0,0X00,0X00,0XC0,0X10,0X38,
|
||||
0X64,0X7F,0X3F,0X9F,0XC0,0X87,0XE1,0XF1,0X0C,0X9E,0X08,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XC6,0X3E,0X00,0X3F,0XFF,0X07,0XC0,0X00,0X00,0XC0,0X30,0X1C,
|
||||
0XC4,0X00,0X31,0X98,0XC0,0X80,0X03,0XB1,0XFC,0XB2,0X08,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0XF8,0X3F,0X07,0XC0,0X00,0X00,0X00,0XC0,0X60,0X0C,
|
||||
0XC4,0X00,0X00,0X90,0X41,0X80,0X02,0X18,0X78,0XC6,0X08,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X01,0XF8,0X3F,0X07,0XC0,0X00,0X00,0X00,0XC0,0XC1,0X04,
|
||||
0XFF,0X00,0X00,0X90,0X41,0X00,0X02,0X08,0X10,0X86,0X08,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X01,0XF8,0X3F,0X07,0XC0,0X00,0X00,0X00,0XC1,0X81,0X8C,
|
||||
0X04,0X00,0X31,0X98,0XC3,0X00,0X03,0X18,0X30,0XC4,0X08,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XFF,0XF9,0XFE,0X38,0XC7,0X3F,0X00,0X00,0X03,0XFB,0XF8,0XFC,
|
||||
0X04,0X00,0X1F,0X0F,0X82,0X00,0X03,0XF0,0X60,0X7C,0X7F,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XFF,0XF9,0XFE,0X38,0XC7,0X3F,0X00,0X00,0X00,0X00,0X00,0X30,
|
||||
0X00,0X00,0X0E,0X07,0X00,0X00,0X00,0XE0,0X00,0X38,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XFF,0XF8,0XFE,0X38,0XC7,0X3F,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X30,0X00,0X38,0X39,0XF8,0X07,0X07,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X30,0X00,0X38,0X39,0XF8,0X07,0X07,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XC1,0XC7,0XC7,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XC1,0XC7,0XC7,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X39,0XC1,0XC7,0XC7,0XC7,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X38,0X07,0XF8,0X07,0X3F,0XC0,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X38,0X07,0XF8,0X07,0X3F,0XC0,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X38,0X07,0XF8,0X07,0XC0,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X38,0X3F,0XC0,0XC7,0XC0,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X31,0XFE,0X38,0X3F,0XC0,0XC7,0XC0,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X30,0X00,0X38,0X00,0X07,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X30,0X00,0X38,0X00,0X07,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X30,0X00,0X38,0X00,0X07,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XFF,0XF9,0XFE,0X3F,0XC0,0XC0,0XC0,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X3F,0XFF,0XF9,0XFE,0X3F,0XC0,0XC0,0XC0,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X02,0X00,0X60,0XFE,0X1F,0XC0,0XC0,0XC0,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
extern const unsigned char Image_logo[];
|
||||
extern const unsigned char Image_logo_revert[];
|
||||
extern const unsigned char IMAGE_DATA[];
|
||||
extern const unsigned char matter_light_on[];
|
||||
extern const unsigned char matter_light_off[];
|
||||
extern const unsigned char qr_code[];
|
||||
extern const unsigned char esp_logo[];
|
||||
extern const unsigned char esp_logo_1[];
|
||||
extern const unsigned char badge_background[];
|
||||
|
||||
/* FILE END */
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Lowpower EVB Example
|
||||
|
||||
For other examples please check:
|
||||
https://github.com/espressif/esp-iot-solution/tree/master/examples
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#ifndef _IOT_LOWPOWER_EVB_EPAPER_H_
|
||||
#define _IOT_LOWPOWER_EVB_EPAPER_H_
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief initialize epaper.
|
||||
*/
|
||||
|
||||
void epaper_display_init();
|
||||
|
||||
void epaper_show_page_loop();
|
||||
|
||||
void epaper_show_page_init(void);
|
||||
|
||||
void epaper_matter_code(void);
|
||||
|
||||
void epaper_light_power(bool power);
|
||||
|
||||
void display_commission_qr_code();
|
||||
|
||||
void epaper_display_espressif_logo();
|
||||
|
||||
void display_vcard(char *vcard, uint32_t x_offset, uint32_t y_offset);
|
||||
|
||||
void epaper_display_badge(char *name, char *company_name, char *email, char *contact, char *event_name);
|
||||
|
||||
/**
|
||||
* @brief disable epaper.
|
||||
*/
|
||||
void epaper_disable();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
/* Lowpower EVB Example
|
||||
|
||||
For other examples please check:
|
||||
https://github.com/espressif/esp-iot-solution/tree/master/examples
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "epaper.h"
|
||||
#include "epaper_fonts.h"
|
||||
#include "imagedata.h"
|
||||
#include "lowpower_evb_epaper.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#include "qrcode.h"
|
||||
static const char *TAG = "lowpower_evb_epaper";
|
||||
|
||||
#define EPAPER_POWER_CNTL_IO ((gpio_num_t) 14)
|
||||
|
||||
/* Epaper pin definition */
|
||||
#define MOSI_PIN 23
|
||||
#define SCK_PIN 18
|
||||
#define BUSY_PIN 4
|
||||
#define DC_PIN 17
|
||||
#define RST_PIN 16
|
||||
#define CS_PIN 5
|
||||
|
||||
// CPowerCtrl *epaper_power = NULL;
|
||||
|
||||
static epaper_handle_t epaper = NULL;
|
||||
const uint8_t Whiteboard[4000] = {0x00};
|
||||
|
||||
static void epaper_power_on()
|
||||
{
|
||||
// epaper_power = new CPowerCtrl(EPAPER_POWER_CNTL_IO);
|
||||
// epaper_power->on();
|
||||
}
|
||||
|
||||
static void epaper_gpio_init()
|
||||
{
|
||||
epaper_conf_t epaper_conf;
|
||||
epaper_conf.busy_pin = BUSY_PIN;
|
||||
epaper_conf.cs_pin = CS_PIN;
|
||||
epaper_conf.dc_pin = DC_PIN;
|
||||
epaper_conf.mosi_pin = MOSI_PIN;
|
||||
epaper_conf.reset_pin = RST_PIN;
|
||||
epaper_conf.sck_pin = SCK_PIN;
|
||||
|
||||
gpio_config_t epaper_gpio_config;
|
||||
epaper_gpio_config.pin_bit_mask = ((uint64_t)(((uint64_t)1)<<epaper_conf.busy_pin));
|
||||
epaper_gpio_config.mode = GPIO_MODE_INPUT;
|
||||
epaper_gpio_config.pull_down_en = GPIO_PULLDOWN_ENABLE;
|
||||
epaper_gpio_config.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
epaper_gpio_config.intr_type = GPIO_INTR_DISABLE;
|
||||
gpio_config(&epaper_gpio_config);
|
||||
|
||||
epaper_gpio_config.pin_bit_mask = (1<<epaper_conf.cs_pin) | (1<<epaper_conf.dc_pin) |
|
||||
(1<<epaper_conf.mosi_pin) | (1<<epaper_conf.reset_pin)|
|
||||
(1<<epaper_conf.sck_pin);
|
||||
epaper_gpio_config.mode = GPIO_MODE_OUTPUT;
|
||||
|
||||
gpio_config(&epaper_gpio_config);
|
||||
gpio_set_level((gpio_num_t)epaper_conf.cs_pin, 0);
|
||||
gpio_set_level((gpio_num_t)epaper_conf.dc_pin, 0);
|
||||
gpio_set_level((gpio_num_t)epaper_conf.mosi_pin, 0);
|
||||
gpio_set_level((gpio_num_t)epaper_conf.reset_pin, 0);
|
||||
gpio_set_level((gpio_num_t)epaper_conf.sck_pin, 0);
|
||||
}
|
||||
|
||||
static void epaper_init()
|
||||
{
|
||||
epaper_conf_t epaper_conf;
|
||||
epaper_conf.busy_pin = BUSY_PIN;
|
||||
epaper_conf.cs_pin = CS_PIN;
|
||||
epaper_conf.dc_pin = DC_PIN;
|
||||
epaper_conf.mosi_pin = MOSI_PIN;
|
||||
epaper_conf.reset_pin = RST_PIN;
|
||||
epaper_conf.sck_pin = SCK_PIN;
|
||||
|
||||
epaper_conf.rst_active_level = 0;
|
||||
epaper_conf.dc_lev_data = 1;
|
||||
epaper_conf.dc_lev_cmd = 0;
|
||||
|
||||
epaper_conf.clk_freq_hz = 20 * 1000 * 1000;
|
||||
epaper_conf.spi_host = HSPI_HOST;
|
||||
|
||||
epaper_conf.color_inv = 0;
|
||||
|
||||
ESP_LOGI(TAG, "before epaper init, heap: %ld", esp_get_free_heap_size());
|
||||
epaper = iot_epaper_create(NULL, &epaper_conf);
|
||||
iot_epaper_set_rotate(epaper, 3);
|
||||
}
|
||||
|
||||
void epaper_show_page_loop() //Partial refresh
|
||||
{
|
||||
char string_show[70];
|
||||
static uint16_t time = 0;
|
||||
|
||||
sprintf(string_show, "Time:%d", time);
|
||||
time++;
|
||||
iot_epaper_draw_string(epaper, 50, 110, string_show, &epaper_font_16, 0x0000);
|
||||
iot_epaper_updateWindow(epaper, 50, 110, 100, 18, true);
|
||||
iot_drawBitmapBM(epaper, Whiteboard, 50, 110, 100, 18, GxEPD_BLACK, true);
|
||||
|
||||
}
|
||||
void epaper_matter_code(void) //Display Matter pairing
|
||||
{
|
||||
iot_drawBitmapBM(epaper, Whiteboard, 0, 0, 250, 128, GxEPD_BLACK, true); //clean paint
|
||||
iot_drawBitmapBM(epaper, matter_comminsion, 0, 11, 250, 110, GxEPD_BLACK, true);
|
||||
//iot_epaper_update(epaper);
|
||||
iot_epaper_updateWindow(epaper, 0, 0, 250, 128, true); //make screen pure!
|
||||
}
|
||||
|
||||
void epaper_show_page_init(void) //Display the initial interface
|
||||
{
|
||||
iot_drawBitmapBM(epaper, matter_logo, 0, 0, 250, 122, GxEPD_BLACK, true);
|
||||
iot_epaper_draw_string(epaper, 40, 90, "Badge-Demo", &epaper_font_24, GxEPD_BLACK);
|
||||
//iot_epaper_update(epaper);
|
||||
iot_epaper_updateWindow(epaper, 0, 0, 250, 128, true); //make screen pure!
|
||||
}
|
||||
|
||||
void epaper_display_espressif_logo(void)
|
||||
{
|
||||
// iot_drawBitmapBM(epaper, Whiteboard, 0, 0, 250, 128, GxEPD_BLACK, true);
|
||||
iot_drawBitmapBM(epaper, esp_logo, 0, 0, 250, 122, GxEPD_BLACK, true);
|
||||
iot_epaper_updateWindow(epaper, 0, 0, 250, 128, true); //make screen pure!
|
||||
}
|
||||
|
||||
void epaper_light_power(bool power)
|
||||
{
|
||||
if (power) {
|
||||
iot_drawBitmapBM(epaper, Whiteboard, 0, -7, 250, 128, GxEPD_BLACK, true);
|
||||
iot_drawBitmapBM(epaper, matter_light_on, 0, 0, 250, 122, GxEPD_BLACK, true);
|
||||
iot_epaper_draw_string(epaper, 40, 90, "light On", &epaper_font_24, GxEPD_BLACK);
|
||||
iot_epaper_updateWindow(epaper, 0, 0, 250, 122, true);
|
||||
} else {
|
||||
iot_drawBitmapBM(epaper, Whiteboard, 0, -7, 250, 128, GxEPD_BLACK, true);
|
||||
iot_drawBitmapBM(epaper, matter_light_off, 0, 0, 250, 122, GxEPD_BLACK, true);
|
||||
iot_epaper_draw_string(epaper, 40, 90, "light Off", &epaper_font_24, GxEPD_BLACK);
|
||||
iot_epaper_updateWindow(epaper, 0, 0, 250, 122, true);
|
||||
}
|
||||
}
|
||||
|
||||
void display_commission_qr_code()
|
||||
{
|
||||
iot_drawBitmapBM(epaper, Whiteboard, 0, 0, 250, 122, GxEPD_BLACK, true);
|
||||
iot_drawBitmapBM(epaper, qr_code, 0, -7, 250, 122, GxEPD_BLACK, true);
|
||||
iot_epaper_updateWindow(epaper, 0, 0, 250, 122, true);
|
||||
}
|
||||
|
||||
void display_vcard(char *vcard, uint32_t x_offset, uint32_t y_offset)
|
||||
{
|
||||
QRCode qrcode;
|
||||
uint8_t version = 9, ecc = 1;
|
||||
uint8_t qrcodeData[qrcode_getBufferSize(version)];
|
||||
qrcode_initText(&qrcode, qrcodeData, version, ecc, vcard);
|
||||
for (uint8_t y = 0; y < qrcode.size; y++) {
|
||||
for (uint8_t x = 0; x < qrcode.size; x++) {
|
||||
iot_drawPixel(epaper, x + x_offset, y + y_offset, qrcode_getModule(&qrcode, x, y) ? BLACK_COLORED : UNCOLORED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void epaper_display_badge(char *name, char *company_name, char *email, char *contact, char *event_name)
|
||||
{
|
||||
iot_drawBitmapBM(epaper, Whiteboard, 0, -7, 250, 122, GxEPD_BLACK, true);
|
||||
iot_epaper_updateWindow(epaper, 0, 0, 250, 122, true);
|
||||
iot_drawBitmapBM(epaper, Whiteboard, 0, -7, 250, 122, GxEPD_BLACK, true);
|
||||
iot_epaper_updateWindow(epaper, 0, 0, 250, 122, true);
|
||||
char *vcard;// = (char*) malloc(sizeof(char) * vcard_size);
|
||||
asprintf(&vcard,"BEGIN:VCARD\nVERSION:3.0\nN:%s\nORG:%s\nEMAIL:%s\nTEL;TYPE=voice,work,pref:%s\nEND:VCARD", name, company_name, email, contact);
|
||||
display_vcard(vcard, 137, 60);
|
||||
iot_epaper_draw_string(epaper, 5, 5, name, &epaper_font_meslo_11, GxEPD_BLACK);
|
||||
iot_epaper_draw_string(epaper, 5, 35, company_name, &epaper_font_meslo_11, GxEPD_BLACK);
|
||||
iot_epaper_draw_horizontal_line(epaper, 0, 54, 250, BLACK_COLORED);
|
||||
char event_name_1[19];
|
||||
memcpy(event_name_1, event_name, strlen(event_name) > 19 ? 19 : strlen(event_name));
|
||||
event_name_1[strlen(event_name) > 19 ? 19 : strlen(event_name)] = '\0';
|
||||
iot_epaper_draw_string(epaper, 5, 70, event_name_1, &epaper_font_meslo_8, GxEPD_BLACK);
|
||||
if (strlen(event_name) > 19) {
|
||||
char event_name_2[19];
|
||||
memcpy(event_name_2, &event_name[19], strlen(&event_name[19]) > 19 ? 19 : strlen(&event_name[19]));
|
||||
event_name_2[strlen(&event_name[19]) > 19 ? 19 : strlen(&event_name[19])] = '\0';
|
||||
iot_epaper_draw_string(epaper, 5, 85, event_name_2, &epaper_font_meslo_8, GxEPD_BLACK);
|
||||
}
|
||||
iot_drawBitmapBM(epaper, esp_logo_1, 195, 60, 53, 53, GxEPD_BLACK, true);
|
||||
iot_epaper_updateWindow(epaper, 0, 0, 250, 122, true);
|
||||
free(vcard);
|
||||
}
|
||||
|
||||
void epaper_disable()
|
||||
{
|
||||
iot_epaper_delete(epaper, true);
|
||||
}
|
||||
|
||||
void epaper_display_init()
|
||||
{
|
||||
epaper_gpio_init();
|
||||
epaper_power_on();
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS); // 10ms delay after power on
|
||||
epaper_init();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
set(COMPONENT_SRCS "qrcode.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
set(COMPONENT_NAME "qrcode")
|
||||
register_component()
|
||||
@@ -0,0 +1,867 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* This library is written and maintained by Richard Moore.
|
||||
* Major parts were derived from Project Nayuki's library.
|
||||
*
|
||||
* Copyright (c) 2017 Richard Moore (https://github.com/ricmoo/QRCode)
|
||||
* Copyright (c) 2017 Project Nayuki (https://www.nayuki.io/page/qr-code-generator-library)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Special thanks to Nayuki (https://www.nayuki.io/) from which this library was
|
||||
* heavily inspired and compared against.
|
||||
*
|
||||
* See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp
|
||||
*/
|
||||
|
||||
#include "qrcode.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#if LOCK_VERSION == 0
|
||||
|
||||
static const uint16_t NUM_ERROR_CORRECTION_CODEWORDS[4][40] = {
|
||||
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
|
||||
{ 10, 16, 26, 36, 48, 64, 72, 88, 110, 130, 150, 176, 198, 216, 240, 280, 308, 338, 364, 416, 442, 476, 504, 560, 588, 644, 700, 728, 784, 812, 868, 924, 980, 1036, 1064, 1120, 1204, 1260, 1316, 1372}, // Medium
|
||||
{ 7, 10, 15, 20, 26, 36, 40, 48, 60, 72, 80, 96, 104, 120, 132, 144, 168, 180, 196, 224, 224, 252, 270, 300, 312, 336, 360, 390, 420, 450, 480, 510, 540, 570, 570, 600, 630, 660, 720, 750}, // Low
|
||||
{ 17, 28, 44, 64, 88, 112, 130, 156, 192, 224, 264, 308, 352, 384, 432, 480, 532, 588, 650, 700, 750, 816, 900, 960, 1050, 1110, 1200, 1260, 1350, 1440, 1530, 1620, 1710, 1800, 1890, 1980, 2100, 2220, 2310, 2430}, // High
|
||||
{ 13, 22, 36, 52, 72, 96, 108, 132, 160, 192, 224, 260, 288, 320, 360, 408, 448, 504, 546, 600, 644, 690, 750, 810, 870, 952, 1020, 1050, 1140, 1200, 1290, 1350, 1440, 1530, 1590, 1680, 1770, 1860, 1950, 2040}, // Quartile
|
||||
};
|
||||
|
||||
static const uint8_t NUM_ERROR_CORRECTION_BLOCKS[4][40] = {
|
||||
// Version: (note that index 0 is for padding, and is set to an illegal value)
|
||||
// 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
|
||||
{ 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium
|
||||
{ 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low
|
||||
{ 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High
|
||||
{ 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile
|
||||
};
|
||||
|
||||
static const uint16_t NUM_RAW_DATA_MODULES[40] = {
|
||||
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
|
||||
208, 359, 567, 807, 1079, 1383, 1568, 1936, 2336, 2768, 3232, 3728, 4256, 4651, 5243, 5867, 6523,
|
||||
// 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
7211, 7931, 8683, 9252, 10068, 10916, 11796, 12708, 13652, 14628, 15371, 16411, 17483, 18587,
|
||||
// 32, 33, 34, 35, 36, 37, 38, 39, 40
|
||||
19723, 20891, 22091, 23008, 24272, 25568, 26896, 28256, 29648
|
||||
};
|
||||
|
||||
// @TODO: Put other LOCK_VERSIONS here
|
||||
#elif LOCK_VERSION == 3
|
||||
|
||||
static const int16_t NUM_ERROR_CORRECTION_CODEWORDS[4] = {
|
||||
26, 15, 44, 36
|
||||
};
|
||||
|
||||
static const int8_t NUM_ERROR_CORRECTION_BLOCKS[4] = {
|
||||
1, 1, 2, 2
|
||||
};
|
||||
|
||||
static const uint16_t NUM_RAW_DATA_MODULES = 567;
|
||||
|
||||
#else
|
||||
|
||||
#error Unsupported LOCK_VERSION (add it...)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static int max(int a, int b) {
|
||||
if (a > b) { return a; }
|
||||
return b;
|
||||
}
|
||||
|
||||
/*
|
||||
static int abs(int value) {
|
||||
if (value < 0) { return -value; }
|
||||
return value;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static int8_t getAlphanumeric(char c) {
|
||||
|
||||
if (c >= '0' && c <= '9') { return (c - '0'); }
|
||||
if (c >= 'A' && c <= 'Z') { return (c - 'A' + 10); }
|
||||
|
||||
switch (c) {
|
||||
case ' ': return 36;
|
||||
case '$': return 37;
|
||||
case '%': return 38;
|
||||
case '*': return 39;
|
||||
case '+': return 40;
|
||||
case '-': return 41;
|
||||
case '.': return 42;
|
||||
case '/': return 43;
|
||||
case ':': return 44;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool isAlphanumeric(const char *text, uint16_t length) {
|
||||
while (length != 0) {
|
||||
if (getAlphanumeric(text[--length]) == -1) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool isNumeric(const char *text, uint16_t length) {
|
||||
while (length != 0) {
|
||||
char c = text[--length];
|
||||
if (c < '0' || c > '9') { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// We store the following tightly packed (less 8) in modeInfo
|
||||
// <=9 <=26 <= 40
|
||||
// NUMERIC ( 10, 12, 14);
|
||||
// ALPHANUMERIC ( 9, 11, 13);
|
||||
// BYTE ( 8, 16, 16);
|
||||
static char getModeBits(uint8_t version, uint8_t mode) {
|
||||
// Note: We use 15 instead of 16; since 15 doesn't exist and we cannot store 16 (8 + 8) in 3 bits
|
||||
// hex(int("".join(reversed([('00' + bin(x - 8)[2:])[-3:] for x in [10, 9, 8, 12, 11, 15, 14, 13, 15]])), 2))
|
||||
unsigned int modeInfo = 0x7bbb80a;
|
||||
|
||||
#if LOCK_VERSION == 0 || LOCK_VERSION > 9
|
||||
if (version > 9) { modeInfo >>= 9; }
|
||||
#endif
|
||||
|
||||
#if LOCK_VERSION == 0 || LOCK_VERSION > 26
|
||||
if (version > 26) { modeInfo >>= 9; }
|
||||
#endif
|
||||
|
||||
char result = 8 + ((modeInfo >> (3 * mode)) & 0x07);
|
||||
if (result == 15) { result = 16; }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct BitBucket {
|
||||
uint32_t bitOffsetOrWidth;
|
||||
uint16_t capacityBytes;
|
||||
uint8_t *data;
|
||||
} BitBucket;
|
||||
|
||||
/*
|
||||
void bb_dump(BitBucket *bitBuffer) {
|
||||
printf("Buffer: ");
|
||||
for (uint32_t i = 0; i < bitBuffer->capacityBytes; i++) {
|
||||
printf("%02x", bitBuffer->data[i]);
|
||||
if ((i % 4) == 3) { printf(" "); }
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
*/
|
||||
|
||||
static uint16_t bb_getGridSizeBytes(uint8_t size) {
|
||||
return (((size * size) + 7) / 8);
|
||||
}
|
||||
|
||||
static uint16_t bb_getBufferSizeBytes(uint32_t bits) {
|
||||
return ((bits + 7) / 8);
|
||||
}
|
||||
|
||||
static void bb_initBuffer(BitBucket *bitBuffer, uint8_t *data, int32_t capacityBytes) {
|
||||
bitBuffer->bitOffsetOrWidth = 0;
|
||||
bitBuffer->capacityBytes = capacityBytes;
|
||||
bitBuffer->data = data;
|
||||
|
||||
memset(data, 0, bitBuffer->capacityBytes);
|
||||
}
|
||||
|
||||
static void bb_initGrid(BitBucket *bitGrid, uint8_t *data, uint8_t size) {
|
||||
bitGrid->bitOffsetOrWidth = size;
|
||||
bitGrid->capacityBytes = bb_getGridSizeBytes(size);
|
||||
bitGrid->data = data;
|
||||
|
||||
memset(data, 0, bitGrid->capacityBytes);
|
||||
}
|
||||
|
||||
static void bb_appendBits(BitBucket *bitBuffer, uint32_t val, uint8_t length) {
|
||||
uint32_t offset = bitBuffer->bitOffsetOrWidth;
|
||||
for (int8_t i = length - 1; i >= 0; i--, offset++) {
|
||||
bitBuffer->data[offset >> 3] |= ((val >> i) & 1) << (7 - (offset & 7));
|
||||
}
|
||||
bitBuffer->bitOffsetOrWidth = offset;
|
||||
}
|
||||
/*
|
||||
void bb_setBits(BitBucket *bitBuffer, uint32_t val, int offset, uint8_t length) {
|
||||
for (int8_t i = length - 1; i >= 0; i--, offset++) {
|
||||
bitBuffer->data[offset >> 3] |= ((val >> i) & 1) << (7 - (offset & 7));
|
||||
}
|
||||
}
|
||||
*/
|
||||
static void bb_setBit(BitBucket *bitGrid, uint8_t x, uint8_t y, bool on) {
|
||||
uint32_t offset = y * bitGrid->bitOffsetOrWidth + x;
|
||||
uint8_t mask = 1 << (7 - (offset & 0x07));
|
||||
if (on) {
|
||||
bitGrid->data[offset >> 3] |= mask;
|
||||
} else {
|
||||
bitGrid->data[offset >> 3] &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
static void bb_invertBit(BitBucket *bitGrid, uint8_t x, uint8_t y, bool invert) {
|
||||
uint32_t offset = y * bitGrid->bitOffsetOrWidth + x;
|
||||
uint8_t mask = 1 << (7 - (offset & 0x07));
|
||||
bool on = ((bitGrid->data[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0);
|
||||
if (on ^ invert) {
|
||||
bitGrid->data[offset >> 3] |= mask;
|
||||
} else {
|
||||
bitGrid->data[offset >> 3] &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
static bool bb_getBit(BitBucket *bitGrid, uint8_t x, uint8_t y) {
|
||||
uint32_t offset = y * bitGrid->bitOffsetOrWidth + x;
|
||||
return (bitGrid->data[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
|
||||
// properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
|
||||
// This means it is possible to apply a mask, undo it, and try another mask. Note that a final
|
||||
// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.).
|
||||
static void applyMask(BitBucket *modules, BitBucket *isFunction, uint8_t mask) {
|
||||
uint8_t size = modules->bitOffsetOrWidth;
|
||||
|
||||
for (uint8_t y = 0; y < size; y++) {
|
||||
for (uint8_t x = 0; x < size; x++) {
|
||||
if (bb_getBit(isFunction, x, y)) { continue; }
|
||||
|
||||
bool invert = 0;
|
||||
switch (mask) {
|
||||
case 0: invert = (x + y) % 2 == 0; break;
|
||||
case 1: invert = y % 2 == 0; break;
|
||||
case 2: invert = x % 3 == 0; break;
|
||||
case 3: invert = (x + y) % 3 == 0; break;
|
||||
case 4: invert = (x / 3 + y / 2) % 2 == 0; break;
|
||||
case 5: invert = x * y % 2 + x * y % 3 == 0; break;
|
||||
case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break;
|
||||
case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break;
|
||||
}
|
||||
bb_invertBit(modules, x, y, invert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setFunctionModule(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y, bool on) {
|
||||
bb_setBit(modules, x, y, on);
|
||||
bb_setBit(isFunction, x, y, true);
|
||||
}
|
||||
|
||||
// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y).
|
||||
static void drawFinderPattern(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y) {
|
||||
uint8_t size = modules->bitOffsetOrWidth;
|
||||
|
||||
for (int8_t i = -4; i <= 4; i++) {
|
||||
for (int8_t j = -4; j <= 4; j++) {
|
||||
uint8_t dist = max(abs(i), abs(j)); // Chebyshev/infinity norm
|
||||
int16_t xx = x + j, yy = y + i;
|
||||
if (0 <= xx && xx < size && 0 <= yy && yy < size) {
|
||||
setFunctionModule(modules, isFunction, xx, yy, dist != 2 && dist != 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draws a 5*5 alignment pattern, with the center module at (x, y).
|
||||
static void drawAlignmentPattern(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y) {
|
||||
for (int8_t i = -2; i <= 2; i++) {
|
||||
for (int8_t j = -2; j <= 2; j++) {
|
||||
setFunctionModule(modules, isFunction, x + j, y + i, max(abs(i), abs(j)) != 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draws two copies of the format bits (with its own error correction code)
|
||||
// based on the given mask and this object's error correction level field.
|
||||
static void drawFormatBits(BitBucket *modules, BitBucket *isFunction, uint8_t ecc, uint8_t mask) {
|
||||
|
||||
uint8_t size = modules->bitOffsetOrWidth;
|
||||
|
||||
// Calculate error correction code and pack bits
|
||||
uint32_t data = ecc << 3 | mask; // errCorrLvl is uint2, mask is uint3
|
||||
uint32_t rem = data;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
rem = (rem << 1) ^ ((rem >> 9) * 0x537);
|
||||
}
|
||||
|
||||
data = data << 10 | rem;
|
||||
data ^= 0x5412; // uint15
|
||||
|
||||
// Draw first copy
|
||||
for (uint8_t i = 0; i <= 5; i++) {
|
||||
setFunctionModule(modules, isFunction, 8, i, ((data >> i) & 1) != 0);
|
||||
}
|
||||
|
||||
setFunctionModule(modules, isFunction, 8, 7, ((data >> 6) & 1) != 0);
|
||||
setFunctionModule(modules, isFunction, 8, 8, ((data >> 7) & 1) != 0);
|
||||
setFunctionModule(modules, isFunction, 7, 8, ((data >> 8) & 1) != 0);
|
||||
|
||||
for (int8_t i = 9; i < 15; i++) {
|
||||
setFunctionModule(modules, isFunction, 14 - i, 8, ((data >> i) & 1) != 0);
|
||||
}
|
||||
|
||||
// Draw second copy
|
||||
for (int8_t i = 0; i <= 7; i++) {
|
||||
setFunctionModule(modules, isFunction, size - 1 - i, 8, ((data >> i) & 1) != 0);
|
||||
}
|
||||
|
||||
for (int8_t i = 8; i < 15; i++) {
|
||||
setFunctionModule(modules, isFunction, 8, size - 15 + i, ((data >> i) & 1) != 0);
|
||||
}
|
||||
|
||||
setFunctionModule(modules, isFunction, 8, size - 8, true);
|
||||
}
|
||||
|
||||
|
||||
// Draws two copies of the version bits (with its own error correction code),
|
||||
// based on this object's version field (which only has an effect for 7 <= version <= 40).
|
||||
static void drawVersion(BitBucket *modules, BitBucket *isFunction, uint8_t version) {
|
||||
|
||||
int8_t size = modules->bitOffsetOrWidth;
|
||||
|
||||
#if LOCK_VERSION != 0 && LOCK_VERSION < 7
|
||||
return;
|
||||
|
||||
#else
|
||||
if (version < 7) { return; }
|
||||
|
||||
// Calculate error correction code and pack bits
|
||||
uint32_t rem = version; // version is uint6, in the range [7, 40]
|
||||
for (uint8_t i = 0; i < 12; i++) {
|
||||
rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
|
||||
}
|
||||
|
||||
uint32_t data = version << 12 | rem; // uint18
|
||||
|
||||
// Draw two copies
|
||||
for (uint8_t i = 0; i < 18; i++) {
|
||||
bool bit = ((data >> i) & 1) != 0;
|
||||
uint8_t a = size - 11 + i % 3, b = i / 3;
|
||||
setFunctionModule(modules, isFunction, a, b, bit);
|
||||
setFunctionModule(modules, isFunction, b, a, bit);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void drawFunctionPatterns(BitBucket *modules, BitBucket *isFunction, uint8_t version, uint8_t ecc) {
|
||||
|
||||
uint8_t size = modules->bitOffsetOrWidth;
|
||||
|
||||
// Draw the horizontal and vertical timing patterns
|
||||
for (uint8_t i = 0; i < size; i++) {
|
||||
setFunctionModule(modules, isFunction, 6, i, i % 2 == 0);
|
||||
setFunctionModule(modules, isFunction, i, 6, i % 2 == 0);
|
||||
}
|
||||
|
||||
// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
|
||||
drawFinderPattern(modules, isFunction, 3, 3);
|
||||
drawFinderPattern(modules, isFunction, size - 4, 3);
|
||||
drawFinderPattern(modules, isFunction, 3, size - 4);
|
||||
|
||||
#if LOCK_VERSION == 0 || LOCK_VERSION > 1
|
||||
|
||||
if (version > 1) {
|
||||
|
||||
// Draw the numerous alignment patterns
|
||||
|
||||
uint8_t alignCount = version / 7 + 2;
|
||||
uint8_t step;
|
||||
if (version != 32) {
|
||||
step = (version * 4 + alignCount * 2 + 1) / (2 * alignCount - 2) * 2; // ceil((size - 13) / (2*numAlign - 2)) * 2
|
||||
} else { // C-C-C-Combo breaker!
|
||||
step = 26;
|
||||
}
|
||||
|
||||
uint8_t alignPositionIndex = alignCount - 1;
|
||||
uint8_t alignPosition[alignCount];
|
||||
|
||||
alignPosition[0] = 6;
|
||||
|
||||
uint8_t size = version * 4 + 17;
|
||||
for (uint8_t i = 0, pos = size - 7; i < alignCount - 1; i++, pos -= step) {
|
||||
alignPosition[alignPositionIndex--] = pos;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < alignCount; i++) {
|
||||
for (uint8_t j = 0; j < alignCount; j++) {
|
||||
if ((i == 0 && j == 0) || (i == 0 && j == alignCount - 1) || (i == alignCount - 1 && j == 0)) {
|
||||
continue; // Skip the three finder corners
|
||||
} else {
|
||||
drawAlignmentPattern(modules, isFunction, alignPosition[i], alignPosition[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Draw configuration data
|
||||
drawFormatBits(modules, isFunction, ecc, 0); // Dummy mask value; overwritten later in the constructor
|
||||
drawVersion(modules, isFunction, version);
|
||||
}
|
||||
|
||||
|
||||
// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
|
||||
// data area of this QR Code symbol. Function modules need to be marked off before this is called.
|
||||
static void drawCodewords(BitBucket *modules, BitBucket *isFunction, BitBucket *codewords) {
|
||||
|
||||
uint32_t bitLength = codewords->bitOffsetOrWidth;
|
||||
uint8_t *data = codewords->data;
|
||||
|
||||
uint8_t size = modules->bitOffsetOrWidth;
|
||||
|
||||
// Bit index into the data
|
||||
uint32_t i = 0;
|
||||
|
||||
// Do the funny zigzag scan
|
||||
for (int16_t right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair
|
||||
if (right == 6) { right = 5; }
|
||||
|
||||
for (uint8_t vert = 0; vert < size; vert++) { // Vertical counter
|
||||
for (int j = 0; j < 2; j++) {
|
||||
uint8_t x = right - j; // Actual x coordinate
|
||||
bool upwards = ((right & 2) == 0) ^ (x < 6);
|
||||
uint8_t y = upwards ? size - 1 - vert : vert; // Actual y coordinate
|
||||
if (!bb_getBit(isFunction, x, y) && i < bitLength) {
|
||||
bb_setBit(modules, x, y, ((data[i >> 3] >> (7 - (i & 7))) & 1) != 0);
|
||||
i++;
|
||||
}
|
||||
// If there are any remainder bits (0 to 7), they are already
|
||||
// set to 0/false/white when the grid of modules was initialized
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define PENALTY_N1 3
|
||||
#define PENALTY_N2 3
|
||||
#define PENALTY_N3 40
|
||||
#define PENALTY_N4 10
|
||||
|
||||
// Calculates and returns the penalty score based on state of this QR Code's current modules.
|
||||
// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
|
||||
// @TODO: This can be optimized by working with the bytes instead of bits.
|
||||
static uint32_t getPenaltyScore(BitBucket *modules) {
|
||||
uint32_t result = 0;
|
||||
|
||||
uint8_t size = modules->bitOffsetOrWidth;
|
||||
|
||||
// Adjacent modules in row having same color
|
||||
for (uint8_t y = 0; y < size; y++) {
|
||||
|
||||
bool colorX = bb_getBit(modules, 0, y);
|
||||
for (uint8_t x = 1, runX = 1; x < size; x++) {
|
||||
bool cx = bb_getBit(modules, x, y);
|
||||
if (cx != colorX) {
|
||||
colorX = cx;
|
||||
runX = 1;
|
||||
|
||||
} else {
|
||||
runX++;
|
||||
if (runX == 5) {
|
||||
result += PENALTY_N1;
|
||||
} else if (runX > 5) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adjacent modules in column having same color
|
||||
for (uint8_t x = 0; x < size; x++) {
|
||||
bool colorY = bb_getBit(modules, x, 0);
|
||||
for (uint8_t y = 1, runY = 1; y < size; y++) {
|
||||
bool cy = bb_getBit(modules, x, y);
|
||||
if (cy != colorY) {
|
||||
colorY = cy;
|
||||
runY = 1;
|
||||
} else {
|
||||
runY++;
|
||||
if (runY == 5) {
|
||||
result += PENALTY_N1;
|
||||
} else if (runY > 5) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t black = 0;
|
||||
for (uint8_t y = 0; y < size; y++) {
|
||||
uint16_t bitsRow = 0, bitsCol = 0;
|
||||
for (uint8_t x = 0; x < size; x++) {
|
||||
bool color = bb_getBit(modules, x, y);
|
||||
|
||||
// 2*2 blocks of modules having same color
|
||||
if (x > 0 && y > 0) {
|
||||
bool colorUL = bb_getBit(modules, x - 1, y - 1);
|
||||
bool colorUR = bb_getBit(modules, x, y - 1);
|
||||
bool colorL = bb_getBit(modules, x - 1, y);
|
||||
if (color == colorUL && color == colorUR && color == colorL) {
|
||||
result += PENALTY_N2;
|
||||
}
|
||||
}
|
||||
|
||||
// Finder-like pattern in rows and columns
|
||||
bitsRow = ((bitsRow << 1) & 0x7FF) | color;
|
||||
bitsCol = ((bitsCol << 1) & 0x7FF) | bb_getBit(modules, y, x);
|
||||
|
||||
// Needs 11 bits accumulated
|
||||
if (x >= 10) {
|
||||
if (bitsRow == 0x05D || bitsRow == 0x5D0) {
|
||||
result += PENALTY_N3;
|
||||
}
|
||||
if (bitsCol == 0x05D || bitsCol == 0x5D0) {
|
||||
result += PENALTY_N3;
|
||||
}
|
||||
}
|
||||
|
||||
// Balance of black and white modules
|
||||
if (color) { black++; }
|
||||
}
|
||||
}
|
||||
|
||||
// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
|
||||
uint16_t total = size * size;
|
||||
for (uint16_t k = 0; black * 20 < (9 - k) * total || black * 20 > (11 + k) * total; k++) {
|
||||
result += PENALTY_N4;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint8_t rs_multiply(uint8_t x, uint8_t y) {
|
||||
// Russian peasant multiplication
|
||||
// See: https://en.wikipedia.org/wiki/Ancient_Egyptian_multiplication
|
||||
uint16_t z = 0;
|
||||
for (int8_t i = 7; i >= 0; i--) {
|
||||
z = (z << 1) ^ ((z >> 7) * 0x11D);
|
||||
z ^= ((y >> i) & 1) * x;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
static void rs_init(uint8_t degree, uint8_t *coeff) {
|
||||
memset(coeff, 0, degree);
|
||||
coeff[degree - 1] = 1;
|
||||
|
||||
// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
|
||||
// drop the highest term, and store the rest of the coefficients in order of descending powers.
|
||||
// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
|
||||
uint16_t root = 1;
|
||||
for (uint8_t i = 0; i < degree; i++) {
|
||||
// Multiply the current product by (x - r^i)
|
||||
for (uint8_t j = 0; j < degree; j++) {
|
||||
coeff[j] = rs_multiply(coeff[j], root);
|
||||
if (j + 1 < degree) {
|
||||
coeff[j] ^= coeff[j + 1];
|
||||
}
|
||||
}
|
||||
root = (root << 1) ^ ((root >> 7) * 0x11D); // Multiply by 0x02 mod GF(2^8/0x11D)
|
||||
}
|
||||
}
|
||||
|
||||
static void rs_getRemainder(uint8_t degree, uint8_t *coeff, uint8_t *data, uint8_t length, uint8_t *result, uint8_t stride) {
|
||||
// Compute the remainder by performing polynomial division
|
||||
|
||||
//for (uint8_t i = 0; i < degree; i++) { result[] = 0; }
|
||||
//memset(result, 0, degree);
|
||||
|
||||
for (uint8_t i = 0; i < length; i++) {
|
||||
uint8_t factor = data[i] ^ result[0];
|
||||
for (uint8_t j = 1; j < degree; j++) {
|
||||
result[(j - 1) * stride] = result[j * stride];
|
||||
}
|
||||
result[(degree - 1) * stride] = 0;
|
||||
|
||||
for (uint8_t j = 0; j < degree; j++) {
|
||||
result[j * stride] ^= rs_multiply(coeff[j], factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int8_t encodeDataCodewords(BitBucket *dataCodewords, const uint8_t *text, uint16_t length, uint8_t version) {
|
||||
int8_t mode = MODE_BYTE;
|
||||
|
||||
if (isNumeric((char*)text, length)) {
|
||||
mode = MODE_NUMERIC;
|
||||
bb_appendBits(dataCodewords, 1 << MODE_NUMERIC, 4);
|
||||
bb_appendBits(dataCodewords, length, getModeBits(version, MODE_NUMERIC));
|
||||
|
||||
uint16_t accumData = 0;
|
||||
uint8_t accumCount = 0;
|
||||
for (uint16_t i = 0; i < length; i++) {
|
||||
accumData = accumData * 10 + ((char)(text[i]) - '0');
|
||||
accumCount++;
|
||||
if (accumCount == 3) {
|
||||
bb_appendBits(dataCodewords, accumData, 10);
|
||||
accumData = 0;
|
||||
accumCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 or 2 digits remaining
|
||||
if (accumCount > 0) {
|
||||
bb_appendBits(dataCodewords, accumData, accumCount * 3 + 1);
|
||||
}
|
||||
|
||||
} else if (isAlphanumeric((char*)text, length)) {
|
||||
mode = MODE_ALPHANUMERIC;
|
||||
bb_appendBits(dataCodewords, 1 << MODE_ALPHANUMERIC, 4);
|
||||
bb_appendBits(dataCodewords, length, getModeBits(version, MODE_ALPHANUMERIC));
|
||||
|
||||
uint16_t accumData = 0;
|
||||
uint8_t accumCount = 0;
|
||||
for (uint16_t i = 0; i < length; i++) {
|
||||
accumData = accumData * 45 + getAlphanumeric((char)(text[i]));
|
||||
accumCount++;
|
||||
if (accumCount == 2) {
|
||||
bb_appendBits(dataCodewords, accumData, 11);
|
||||
accumData = 0;
|
||||
accumCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 character remaining
|
||||
if (accumCount > 0) {
|
||||
bb_appendBits(dataCodewords, accumData, 6);
|
||||
}
|
||||
|
||||
} else {
|
||||
bb_appendBits(dataCodewords, 1 << MODE_BYTE, 4);
|
||||
bb_appendBits(dataCodewords, length, getModeBits(version, MODE_BYTE));
|
||||
for (uint16_t i = 0; i < length; i++) {
|
||||
bb_appendBits(dataCodewords, (char)(text[i]), 8);
|
||||
}
|
||||
}
|
||||
|
||||
//bb_setBits(dataCodewords, length, 4, getModeBits(version, mode));
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket *data) {
|
||||
|
||||
// See: http://www.thonky.com/qr-code-tutorial/structure-final-message
|
||||
|
||||
#if LOCK_VERSION == 0
|
||||
uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc][version - 1];
|
||||
uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc][version - 1];
|
||||
uint16_t moduleCount = NUM_RAW_DATA_MODULES[version - 1];
|
||||
#else
|
||||
uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc];
|
||||
uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc];
|
||||
uint16_t moduleCount = NUM_RAW_DATA_MODULES;
|
||||
#endif
|
||||
|
||||
uint8_t blockEccLen = totalEcc / numBlocks;
|
||||
uint8_t numShortBlocks = numBlocks - moduleCount / 8 % numBlocks;
|
||||
uint8_t shortBlockLen = moduleCount / 8 / numBlocks;
|
||||
|
||||
uint8_t shortDataBlockLen = shortBlockLen - blockEccLen;
|
||||
|
||||
uint8_t result[data->capacityBytes];
|
||||
memset(result, 0, sizeof(result));
|
||||
|
||||
uint8_t coeff[blockEccLen];
|
||||
rs_init(blockEccLen, coeff);
|
||||
|
||||
uint16_t offset = 0;
|
||||
uint8_t *dataBytes = data->data;
|
||||
|
||||
|
||||
// Interleave all short blocks
|
||||
for (uint8_t i = 0; i < shortDataBlockLen; i++) {
|
||||
uint16_t index = i;
|
||||
uint8_t stride = shortDataBlockLen;
|
||||
for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) {
|
||||
result[offset++] = dataBytes[index];
|
||||
|
||||
#if LOCK_VERSION == 0 || LOCK_VERSION >= 5
|
||||
if (blockNum == numShortBlocks) { stride++; }
|
||||
#endif
|
||||
index += stride;
|
||||
}
|
||||
}
|
||||
|
||||
// Version less than 5 only have short blocks
|
||||
#if LOCK_VERSION == 0 || LOCK_VERSION >= 5
|
||||
{
|
||||
// Interleave long blocks
|
||||
uint16_t index = shortDataBlockLen * (numShortBlocks + 1);
|
||||
uint8_t stride = shortDataBlockLen;
|
||||
for (uint8_t blockNum = 0; blockNum < numBlocks - numShortBlocks; blockNum++) {
|
||||
result[offset++] = dataBytes[index];
|
||||
|
||||
if (blockNum == 0) { stride++; }
|
||||
index += stride;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Add all ecc blocks, interleaved
|
||||
uint8_t blockSize = shortDataBlockLen;
|
||||
for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) {
|
||||
|
||||
#if LOCK_VERSION == 0 || LOCK_VERSION >= 5
|
||||
if (blockNum == numShortBlocks) { blockSize++; }
|
||||
#endif
|
||||
rs_getRemainder(blockEccLen, coeff, dataBytes, blockSize, &result[offset + blockNum], numBlocks);
|
||||
dataBytes += blockSize;
|
||||
}
|
||||
|
||||
memcpy(data->data, result, data->capacityBytes);
|
||||
data->bitOffsetOrWidth = moduleCount;
|
||||
}
|
||||
|
||||
// We store the Format bits tightly packed into a single byte (each of the 4 modes is 2 bits)
|
||||
// The format bits can be determined by ECC_FORMAT_BITS >> (2 * ecc)
|
||||
static const uint8_t ECC_FORMAT_BITS = (0x02 << 6) | (0x03 << 4) | (0x00 << 2) | (0x01 << 0);
|
||||
|
||||
|
||||
|
||||
uint16_t qrcode_getBufferSize(uint8_t version) {
|
||||
return bb_getGridSizeBytes(4 * version + 17);
|
||||
}
|
||||
|
||||
// @TODO: Return error if data is too big.
|
||||
int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length) {
|
||||
uint8_t size = version * 4 + 17;
|
||||
qrcode->version = version;
|
||||
qrcode->size = size;
|
||||
qrcode->ecc = ecc;
|
||||
qrcode->modules = modules;
|
||||
|
||||
uint8_t eccFormatBits = (ECC_FORMAT_BITS >> (2 * ecc)) & 0x03;
|
||||
|
||||
#if LOCK_VERSION == 0
|
||||
uint16_t moduleCount = NUM_RAW_DATA_MODULES[version - 1];
|
||||
uint16_t dataCapacity = moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits][version - 1];
|
||||
#else
|
||||
version = LOCK_VERSION;
|
||||
uint16_t moduleCount = NUM_RAW_DATA_MODULES;
|
||||
uint16_t dataCapacity = moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits];
|
||||
#endif
|
||||
|
||||
struct BitBucket codewords;
|
||||
uint8_t codewordBytes[bb_getBufferSizeBytes(moduleCount)];
|
||||
bb_initBuffer(&codewords, codewordBytes, (int32_t)sizeof(codewordBytes));
|
||||
|
||||
// Place the data code words into the buffer
|
||||
int8_t mode = encodeDataCodewords(&codewords, data, length, version);
|
||||
|
||||
if (mode < 0) { return -1; }
|
||||
qrcode->mode = mode;
|
||||
|
||||
// Add terminator and pad up to a byte if applicable
|
||||
uint32_t padding = (dataCapacity * 8) - codewords.bitOffsetOrWidth;
|
||||
if (padding > 4) { padding = 4; }
|
||||
bb_appendBits(&codewords, 0, padding);
|
||||
bb_appendBits(&codewords, 0, (8 - codewords.bitOffsetOrWidth % 8) % 8);
|
||||
|
||||
// Pad with alternate bytes until data capacity is reached
|
||||
for (uint8_t padByte = 0xEC; codewords.bitOffsetOrWidth < (dataCapacity * 8); padByte ^= 0xEC ^ 0x11) {
|
||||
bb_appendBits(&codewords, padByte, 8);
|
||||
}
|
||||
|
||||
BitBucket modulesGrid;
|
||||
bb_initGrid(&modulesGrid, modules, size);
|
||||
|
||||
BitBucket isFunctionGrid;
|
||||
uint8_t isFunctionGridBytes[bb_getGridSizeBytes(size)];
|
||||
bb_initGrid(&isFunctionGrid, isFunctionGridBytes, size);
|
||||
|
||||
// Draw function patterns, draw all codewords, do masking
|
||||
drawFunctionPatterns(&modulesGrid, &isFunctionGrid, version, eccFormatBits);
|
||||
performErrorCorrection(version, eccFormatBits, &codewords);
|
||||
drawCodewords(&modulesGrid, &isFunctionGrid, &codewords);
|
||||
|
||||
// Find the best (lowest penalty) mask
|
||||
uint8_t mask = 0;
|
||||
int32_t minPenalty = INT32_MAX;
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
drawFormatBits(&modulesGrid, &isFunctionGrid, eccFormatBits, i);
|
||||
applyMask(&modulesGrid, &isFunctionGrid, i);
|
||||
int penalty = getPenaltyScore(&modulesGrid);
|
||||
if (penalty < minPenalty) {
|
||||
mask = i;
|
||||
minPenalty = penalty;
|
||||
}
|
||||
applyMask(&modulesGrid, &isFunctionGrid, i); // Undoes the mask due to XOR
|
||||
}
|
||||
|
||||
qrcode->mask = mask;
|
||||
|
||||
// Overwrite old format bits
|
||||
drawFormatBits(&modulesGrid, &isFunctionGrid, eccFormatBits, mask);
|
||||
|
||||
// Apply the final choice of mask
|
||||
applyMask(&modulesGrid, &isFunctionGrid, mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data) {
|
||||
return qrcode_initBytes(qrcode, modules, version, ecc, (uint8_t*)data, strlen(data));
|
||||
}
|
||||
|
||||
bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y) {
|
||||
if (x < 0 || x >= qrcode->size || y < 0 || y >= qrcode->size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t offset = y * qrcode->size + x;
|
||||
return (qrcode->modules[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
uint8_t qrcode_getHexLength(QRCode *qrcode) {
|
||||
return ((qrcode->size * qrcode->size) + 7) / 4;
|
||||
}
|
||||
|
||||
void qrcode_getHex(QRCode *qrcode, char *result) {
|
||||
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* This library is written and maintained by Richard Moore.
|
||||
* Major parts were derived from Project Nayuki's library.
|
||||
*
|
||||
* Copyright (c) 2017 Richard Moore (https://github.com/ricmoo/QRCode)
|
||||
* Copyright (c) 2017 Project Nayuki (https://www.nayuki.io/page/qr-code-generator-library)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Special thanks to Nayuki (https://www.nayuki.io/) from which this library was
|
||||
* heavily inspired and compared against.
|
||||
*
|
||||
* See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __QRCODE_H_
|
||||
#define __QRCODE_H_
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
static const bool false = 0;
|
||||
static const bool true = 1;
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// QR Code Format Encoding
|
||||
#define MODE_NUMERIC 0
|
||||
#define MODE_ALPHANUMERIC 1
|
||||
#define MODE_BYTE 2
|
||||
|
||||
|
||||
// Error Correction Code Levels
|
||||
#define ECC_LOW 0
|
||||
#define ECC_MEDIUM 1
|
||||
#define ECC_QUARTILE 2
|
||||
#define ECC_HIGH 3
|
||||
|
||||
|
||||
// If set to non-zero, this library can ONLY produce QR codes at that version
|
||||
// This saves a lot of dynamic memory, as the codeword tables are skipped
|
||||
#ifndef LOCK_VERSION
|
||||
#define LOCK_VERSION 0
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct QRCode {
|
||||
uint8_t version;
|
||||
uint8_t size;
|
||||
uint8_t ecc;
|
||||
uint8_t mode;
|
||||
uint8_t mask;
|
||||
uint8_t *modules;
|
||||
} QRCode;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
|
||||
uint16_t qrcode_getBufferSize(uint8_t version);
|
||||
|
||||
int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data);
|
||||
int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length);
|
||||
|
||||
bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif /* __QRCODE_H_ */
|
||||
@@ -0,0 +1,5 @@
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS ".")
|
||||
|
||||
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H")
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <device.h>
|
||||
#include <esp_matter.h>
|
||||
#include <led_driver.h>
|
||||
|
||||
#include <app_priv.h>
|
||||
|
||||
#include <app/server/CommissioningWindowManager.h>
|
||||
#include <app/server/Server.h>
|
||||
|
||||
#include <lowpower_evb_epaper.h>
|
||||
|
||||
using namespace chip::app::Clusters;
|
||||
using namespace esp_matter;
|
||||
|
||||
static const char *TAG = "app_driver";
|
||||
extern uint16_t light_endpoint_id;
|
||||
|
||||
static bool nodelabel_input = false;
|
||||
bool badge_cluster_input_exists = false;
|
||||
|
||||
static esp_err_t set_default_epaper(esp_matter_attr_val_t *val)
|
||||
{
|
||||
epaper_light_power(val->val.b);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Do any conversions/remapping for the actual value here */
|
||||
static esp_err_t app_driver_light_set_power(led_driver_handle_t handle, esp_matter_attr_val_t *val)
|
||||
{
|
||||
return set_default_epaper(val);
|
||||
}
|
||||
|
||||
static esp_err_t set_badge_name(esp_matter_attr_val_t *val)
|
||||
{
|
||||
if (val->val.a.b[0]) {
|
||||
if (!strchr((char*)val->val.a.b, '/')) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
uint8_t* buffer = (uint8_t*)malloc(val->val.a.s * sizeof(uint8_t) + 1);
|
||||
memcpy(buffer, val->val.a.b, val->val.a.s);
|
||||
buffer[val->val.a.s] = '\0';
|
||||
char *name = strtok((char*)buffer, "/");
|
||||
char *company_name = strtok(NULL, "\0");
|
||||
epaper_display_badge(name, company_name, "\0", "\0", "CSA Member Meeting November 2023");
|
||||
nodelabel_input = true;
|
||||
free(buffer);
|
||||
return ESP_OK;
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
static void app_driver_button_toggle_cb(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Toggle button pressed");
|
||||
uint16_t endpoint_id = light_endpoint_id;
|
||||
uint32_t cluster_id = OnOff::Id;
|
||||
uint32_t attribute_id = OnOff::Attributes::OnOff::Id;
|
||||
|
||||
node_t *node = node::get();
|
||||
endpoint_t *endpoint = endpoint::get(node, endpoint_id);
|
||||
cluster_t *cluster = cluster::get(endpoint, cluster_id);
|
||||
attribute_t *attribute = attribute::get(cluster, attribute_id);
|
||||
|
||||
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||
attribute::get_val(attribute, &val);
|
||||
val.val.b = !val.val.b;
|
||||
attribute::update(endpoint_id, cluster_id, attribute_id, &val);
|
||||
}
|
||||
|
||||
esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id,
|
||||
uint32_t attribute_id, esp_matter_attr_val_t *val)
|
||||
{
|
||||
if (cluster_id == BADGE_CLUSTER_ID) {
|
||||
char vcard_data[MAX_VCARD_ATTR][MAX_ATTR_SIZE];
|
||||
memset(vcard_data, '\0', sizeof(MAX_VCARD_ATTR * MAX_ATTR_SIZE));
|
||||
esp_matter_attr_val_t _val = esp_matter_invalid(NULL);
|
||||
node_t *node = node::get();
|
||||
endpoint_t *endpoint = endpoint::get(node, 0x0);
|
||||
cluster_t *cluster = cluster::get(endpoint, BADGE_CLUSTER_ID);
|
||||
attribute_t *attribute = NULL;
|
||||
|
||||
uint32_t _attribute_id = NAME_ATTRIBUTE_ID;
|
||||
|
||||
for (int i = 0; i < MAX_VCARD_ATTR; i++) {
|
||||
if (i == attribute_id) {
|
||||
memcpy(vcard_data[i], val->val.a.b, val->val.a.s);
|
||||
vcard_data[i][val->val.a.s] = '\0';
|
||||
_attribute_id++;
|
||||
continue;
|
||||
}
|
||||
attribute = attribute::get(cluster, _attribute_id);
|
||||
attribute::get_val(attribute, &_val);
|
||||
memcpy(vcard_data[i], _val.val.a.b, _val.val.a.s);
|
||||
vcard_data[i][_val.val.a.s] = '\0';
|
||||
_attribute_id++;
|
||||
}
|
||||
badge_cluster_input_exists = true;
|
||||
epaper_display_badge(vcard_data[NAME], vcard_data[COMPANY_NAME], vcard_data[EMAIL], vcard_data[CONTACT], vcard_data[EVENT_NAME]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Update NodeLabel based name and company_name input */
|
||||
if (cluster_id == BasicInformation::Id && attribute_id == BasicInformation::Attributes::NodeLabel::Id && !badge_cluster_input_exists) {
|
||||
if(set_badge_name(val) == ESP_OK)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Update Light Display */
|
||||
if (endpoint_id == light_endpoint_id && !nodelabel_input && !badge_cluster_input_exists) {
|
||||
if (cluster_id == OnOff::Id) {
|
||||
if (attribute_id == OnOff::Attributes::OnOff::Id) {
|
||||
epaper_light_power(val->val.b);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t app_driver_light_set_defaults(uint16_t endpoint_id)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
void *priv_data = endpoint::get_priv_data(endpoint_id);
|
||||
led_driver_handle_t handle = (led_driver_handle_t)priv_data;
|
||||
node_t *node = node::get();
|
||||
endpoint_t *endpoint = endpoint::get(node, endpoint_id);
|
||||
cluster_t *cluster = NULL;
|
||||
attribute_t *attribute = NULL;
|
||||
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||
|
||||
endpoint = endpoint::get(node, 0x0);
|
||||
cluster = cluster::get(endpoint, BADGE_CLUSTER_ID);
|
||||
attribute = attribute::get(cluster, NAME_ATTRIBUTE_ID);
|
||||
attribute::get_val(attribute, &val);
|
||||
if (val.val.a.b[NAME]) {
|
||||
char vcard_data[MAX_VCARD_ATTR][MAX_ATTR_SIZE];
|
||||
memset(vcard_data, '\0', sizeof(vcard_data));
|
||||
int i = 0;
|
||||
uint32_t attribute_id = NAME_ATTRIBUTE_ID;
|
||||
do {
|
||||
esp_matter_attr_val_t _val = esp_matter_invalid(NULL);
|
||||
attribute = attribute::get(cluster, attribute_id);
|
||||
attribute::get_val(attribute, &_val);
|
||||
memcpy(vcard_data[i], _val.val.a.b, _val.val.a.s);
|
||||
vcard_data[i][_val.val.a.s] = '\0';
|
||||
attribute_id++;
|
||||
i++;
|
||||
} while (i < MAX_VCARD_ATTR);
|
||||
badge_cluster_input_exists = true;
|
||||
epaper_display_badge(vcard_data[NAME], vcard_data[COMPANY_NAME], vcard_data[EMAIL], vcard_data[CONTACT], vcard_data[EVENT_NAME]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* If nodelabel value is set then display the nodelabel_input */
|
||||
cluster = cluster::get(endpoint, BasicInformation::Id);
|
||||
attribute = attribute::get(cluster, BasicInformation::Attributes::NodeLabel::Id);
|
||||
attribute::get_val(attribute, &val);
|
||||
if (val.val.a.s && !badge_cluster_input_exists) {
|
||||
set_badge_name(&val);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Setting power */
|
||||
if (!nodelabel_input) {
|
||||
cluster = cluster::get(endpoint, OnOff::Id);
|
||||
attribute = attribute::get(cluster, OnOff::Attributes::OnOff::Id);
|
||||
attribute::get_val(attribute, &val);
|
||||
if (chip::Server::GetInstance().GetFabricTable().FabricCount())
|
||||
err |= app_driver_light_set_power(handle, &val);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void factory_reset_badge(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Factory Resetting the Espressif Badge");
|
||||
esp_matter::factory_reset();
|
||||
}
|
||||
|
||||
app_driver_handle_t app_driver_button_init()
|
||||
{
|
||||
/* Initialize button */
|
||||
button_config_t config = {
|
||||
.type = BUTTON_TYPE_GPIO,
|
||||
.gpio_button_config = {
|
||||
.gpio_num = 39,
|
||||
.active_level = 0,
|
||||
}
|
||||
};
|
||||
button_handle_t handle = iot_button_create(&config);
|
||||
iot_button_register_cb(handle, BUTTON_PRESS_DOWN, app_driver_button_toggle_cb, NULL);
|
||||
iot_button_register_cb(handle, BUTTON_LONG_PRESS_START, factory_reset_badge, NULL);
|
||||
return (app_driver_handle_t)handle;
|
||||
}
|
||||
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <esp_err.h>
|
||||
#include <esp_log.h>
|
||||
#include <nvs_flash.h>
|
||||
|
||||
#include <esp_matter.h>
|
||||
#include <esp_matter_console.h>
|
||||
#include <esp_matter_ota.h>
|
||||
#include <esp_matter_attribute_utils.h>
|
||||
|
||||
#include <app_priv.h>
|
||||
#include <app_reset.h>
|
||||
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
|
||||
#include <platform/ESP32/OpenthreadLauncher.h>
|
||||
#endif
|
||||
|
||||
#include <app/server/CommissioningWindowManager.h>
|
||||
#include <app/server/Server.h>
|
||||
|
||||
#include <epaper.h>
|
||||
#include <lowpower_evb_epaper.h>
|
||||
|
||||
static const char *TAG = "app_main";
|
||||
uint16_t light_endpoint_id = 0;
|
||||
|
||||
using namespace esp_matter;
|
||||
using namespace esp_matter::attribute;
|
||||
using namespace esp_matter::endpoint;
|
||||
using namespace chip::app::Clusters;
|
||||
|
||||
constexpr auto k_timeout_seconds = 300;
|
||||
|
||||
#if CONFIG_ENABLE_ENCRYPTED_OTA
|
||||
extern const char decryption_key_start[] asm("_binary_esp_image_encryption_key_pem_start");
|
||||
extern const char decryption_key_end[] asm("_binary_esp_image_encryption_key_pem_end");
|
||||
|
||||
static const char *s_decryption_key = decryption_key_start;
|
||||
static const uint16_t s_decryption_key_len = decryption_key_end - decryption_key_start;
|
||||
#endif // CONFIG_ENABLE_ENCRYPTED_OTA
|
||||
|
||||
static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg)
|
||||
{
|
||||
switch (event->Type) {
|
||||
case chip::DeviceLayer::DeviceEventType::kInterfaceIpAddressChanged:
|
||||
ESP_LOGI(TAG, "Interface IP Address changed");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kCommissioningComplete:
|
||||
ESP_LOGI(TAG, "Commissioning complete");
|
||||
epaper_light_power(true);
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kFailSafeTimerExpired:
|
||||
ESP_LOGI(TAG, "Commissioning failed, fail safe timer expired");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStarted:
|
||||
ESP_LOGI(TAG, "Commissioning session started");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStopped:
|
||||
ESP_LOGI(TAG, "Commissioning session stopped");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kCommissioningWindowOpened:
|
||||
ESP_LOGI(TAG, "Commissioning window opened");
|
||||
display_commission_qr_code();
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kCommissioningWindowClosed:
|
||||
ESP_LOGI(TAG, "Commissioning window closed");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kFabricRemoved:
|
||||
{
|
||||
ESP_LOGI(TAG, "Fabric removed successfully");
|
||||
if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0)
|
||||
{
|
||||
chip::CommissioningWindowManager & commissionMgr = chip::Server::GetInstance().GetCommissioningWindowManager();
|
||||
constexpr auto kTimeoutSeconds = chip::System::Clock::Seconds16(k_timeout_seconds);
|
||||
if (!commissionMgr.IsCommissioningWindowOpen())
|
||||
{
|
||||
/* After removing last fabric, this example does not remove the Wi-Fi credentials
|
||||
* and still has IP connectivity so, only advertising on DNS-SD.
|
||||
*/
|
||||
CHIP_ERROR err = commissionMgr.OpenBasicCommissioningWindow(kTimeoutSeconds,
|
||||
chip::CommissioningWindowAdvertisement::kDnssdOnly);
|
||||
if (err != CHIP_NO_ERROR)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to open commissioning window, err:%" CHIP_ERROR_FORMAT, err.Format());
|
||||
}
|
||||
}
|
||||
}
|
||||
esp_matter::factory_reset();
|
||||
break;
|
||||
}
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kFabricWillBeRemoved:
|
||||
ESP_LOGI(TAG, "Fabric will be removed");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kFabricUpdated:
|
||||
ESP_LOGI(TAG, "Fabric is updated");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kFabricCommitted:
|
||||
ESP_LOGI(TAG, "Fabric is committed");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t app_identification_cb(identification::callback_type_t type, uint16_t endpoint_id, uint8_t effect_id,
|
||||
uint8_t effect_variant, void *priv_data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Identification callback: type: %u, effect: %u, variant: %u", type, effect_id, effect_variant);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t app_attribute_update_cb(attribute::callback_type_t type, uint16_t endpoint_id, uint32_t cluster_id,
|
||||
uint32_t attribute_id, esp_matter_attr_val_t *val, void *priv_data)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
if (type == PRE_UPDATE) {
|
||||
/* Driver update */
|
||||
app_driver_handle_t driver_handle = (app_driver_handle_t)priv_data;
|
||||
err = app_driver_attribute_update(driver_handle, endpoint_id, cluster_id, attribute_id, val);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#if CONFIG_ENABLE_CHIP_SHELL
|
||||
esp_err_t change_badge_name(int argc, char **argv)
|
||||
{
|
||||
if (argc != 1 || !argv[0]) {
|
||||
ESP_LOGE("CHANGE_BADGE_NAME_CONSOLE", "Usage: matter esp change_name '{UserName}/{CompanyName}/{Email}/{Contact}/{Event Name}'");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
size_t count = 0;
|
||||
|
||||
char delimiter = '/';
|
||||
for (int i = 0; argv[0][i] != '\0'; ++i) {
|
||||
if (delimiter == argv[0][i])
|
||||
++count;
|
||||
}
|
||||
if (count != 4) {
|
||||
ESP_LOGE("CHANGE_BADGE_NAME_CONSOLE", "Usage: matter esp change_name '{UserName}/{CompanyName}/{Email}/{Contact}/{Event Name}'");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
char vcard_data[MAX_VCARD_ATTR][MAX_ATTR_SIZE];
|
||||
char *in_ptr = argv[0];
|
||||
char *o_ptr;
|
||||
int i = 0;
|
||||
while((o_ptr = strsep(&in_ptr, "/")) != NULL) {
|
||||
strcpy(vcard_data[i], o_ptr);
|
||||
i++;
|
||||
}
|
||||
if (i == EVENT_NAME) {
|
||||
strcpy(vcard_data[EVENT_NAME], "\0");
|
||||
}
|
||||
if (chip::Server::GetInstance().GetFabricTable().FabricCount()) {
|
||||
uint16_t endpoint_id = 0x0;
|
||||
uint32_t cluster_id = BADGE_CLUSTER_ID;
|
||||
uint32_t attribute_id = NAME_ATTRIBUTE_ID;
|
||||
for (int i = 0; i < MAX_VCARD_ATTR; i++) {
|
||||
esp_matter_attr_val_t val = esp_matter_long_char_str(vcard_data[i], strlen(vcard_data[i]));
|
||||
attribute::report(endpoint_id, cluster_id, attribute_id, &val);
|
||||
attribute_id++;
|
||||
}
|
||||
badge_cluster_input_exists = true;
|
||||
}
|
||||
epaper_display_badge(vcard_data[NAME], vcard_data[COMPANY_NAME], vcard_data[EMAIL], vcard_data[CONTACT], vcard_data[EVENT_NAME]);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
void display_badge(void *data)
|
||||
{
|
||||
char **vcard_data = (char**)data;
|
||||
epaper_display_badge(vcard_data[NAME], vcard_data[COMPANY_NAME], vcard_data[EMAIL], vcard_data[CONTACT], vcard_data[EVENT_NAME]);
|
||||
free(vcard_data);
|
||||
vcard_data = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
/* Custom command callback to write the badge info */
|
||||
static esp_err_t update_badge_command_info(const ConcreteCommandPath &command_path, TLVReader &tlv_data, void *opaque_ptr)
|
||||
{
|
||||
uint16_t endpoint_id = command_path.mEndpointId;
|
||||
uint32_t cluster_id = command_path.mClusterId;
|
||||
uint32_t command_id = command_path.mCommandId;
|
||||
|
||||
using namespace chip::app;
|
||||
|
||||
ESP_LOGI(TAG, "The endpoint: %d, cluster_id: %ld, command_id : %ld", endpoint_id, cluster_id, command_id);
|
||||
|
||||
if (chip::TLV::kTLVType_Structure != tlv_data.GetType()) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
chip::TLV::TLVType mOuter;
|
||||
if (CHIP_NO_ERROR != tlv_data.EnterContainer(mOuter)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
char **vcard_data = (char**)malloc(sizeof(char*) * MAX_VCARD_ATTR);
|
||||
for (int i = 0; i < MAX_VCARD_ATTR; i++)
|
||||
vcard_data[i] = NULL;
|
||||
while(1) {
|
||||
CHIP_ERROR err = tlv_data.Next();
|
||||
if (err == CHIP_ERROR_END_OF_TLV)
|
||||
break;
|
||||
else if (CHIP_NO_ERROR != err)
|
||||
return ESP_FAIL;
|
||||
|
||||
chip::TLV::Tag tag = tlv_data.GetTag();
|
||||
if (!IsContextTag(tag)) {
|
||||
ESP_LOGE(TAG, "Tag is not valid");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
chip::CharSpan config_value;
|
||||
if (CHIP_NO_ERROR != DataModel::Decode(tlv_data, config_value)) {
|
||||
ESP_LOGE(TAG, "Unable to decode the datamodel");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (TagNumFromTag(tag) >= MAX_VCARD_ATTR) {
|
||||
ESP_LOGE(TAG, "tag not valid");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
uint16_t endpoint_id = 0x0;
|
||||
uint32_t cluster_id = BADGE_CLUSTER_ID;
|
||||
uint32_t attribute_id;
|
||||
size_t size = config_value.size() < 32 ? config_value.size() : 32;
|
||||
esp_matter_attr_val_t val = esp_matter_long_char_str((char*)config_value.data(), size);
|
||||
switch(TagNumFromTag(tag)) {
|
||||
case NAME:
|
||||
attribute_id = NAME_ATTRIBUTE_ID;
|
||||
break;
|
||||
case COMPANY_NAME:
|
||||
attribute_id = COMPANY_NAME_ATTRIBUTE_ID;
|
||||
break;
|
||||
case EMAIL:
|
||||
attribute_id = EMAIL_ATTRIBUTE_ID;
|
||||
break;
|
||||
case CONTACT:
|
||||
attribute_id = CONTACT_ATTRIBUTE_ID;
|
||||
break;
|
||||
case EVENT_NAME:
|
||||
attribute_id = EVENT_NAME_ATTRIBUTE_ID;
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "No such TAG found");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
attribute::report(endpoint_id, cluster_id, attribute_id, &val);
|
||||
vcard_data[TagNumFromTag(tag)] = (char*)malloc(sizeof(char) * (size + 1));
|
||||
memcpy(vcard_data[TagNumFromTag(tag)], config_value.data(), size);
|
||||
vcard_data[TagNumFromTag(tag)][size] = '\0';
|
||||
}
|
||||
if (CHIP_NO_ERROR != tlv_data.ExitContainer(mOuter)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
badge_cluster_input_exists = true;
|
||||
|
||||
if (!vcard_data[NAME] || !vcard_data[COMPANY_NAME] || !vcard_data[EMAIL]) {
|
||||
ESP_LOGW(TAG, "Name, Company Name and Email field are mandatory fields for vcard");
|
||||
}
|
||||
for (int i = 0; i < MAX_VCARD_ATTR; i++) {
|
||||
if (!vcard_data[i]) {
|
||||
vcard_data[i] = (char*)malloc(sizeof(char));
|
||||
vcard_data[i][0] = '\0';
|
||||
}
|
||||
}
|
||||
xTaskCreate(display_badge, "Displaying on the badge", 5120, (void*)vcard_data, 5, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
extern "C" void app_main()
|
||||
{
|
||||
epaper_display_init();
|
||||
epaper_display_espressif_logo();
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
/* Initialize the ESP NVS layer */
|
||||
nvs_flash_init();
|
||||
|
||||
/* Initialize button */
|
||||
app_driver_handle_t button_handle = app_driver_button_init();
|
||||
app_reset_button_register(button_handle);
|
||||
|
||||
/* Create a Matter node and add the mandatory Root Node device type on endpoint 0 */
|
||||
node::config_t node_config;
|
||||
node_t *node = node::create(&node_config, app_attribute_update_cb, app_identification_cb);
|
||||
|
||||
on_off_light::config_t light_config;
|
||||
light_config.on_off.on_off = DEFAULT_POWER;
|
||||
light_config.on_off.lighting.start_up_on_off = nullptr;
|
||||
endpoint_t *endpoint = on_off_light::create(node, &light_config, ENDPOINT_FLAG_NONE, NULL);
|
||||
|
||||
/* These node and endpoint handles can be used to create/add other endpoints and clusters. */
|
||||
if (!node || !endpoint) {
|
||||
ESP_LOGE(TAG, "Matter node creation failed");
|
||||
}
|
||||
|
||||
light_endpoint_id = endpoint::get_id(endpoint);
|
||||
ESP_LOGI(TAG, "Light created with endpoint_id %d", light_endpoint_id);
|
||||
|
||||
/* Create custom badge cluster in basic-information endpoint */
|
||||
uint32_t custom_cluster_id = BADGE_CLUSTER_ID;
|
||||
cluster_t *badge_cluster = cluster::create(endpoint::get(node, 0x0), custom_cluster_id, CLUSTER_FLAG_SERVER);
|
||||
|
||||
/* Create custom attributes in badge cluster for retrieving the vcard properties */
|
||||
attribute::create(badge_cluster, NAME_ATTRIBUTE_ID, ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_long_char_str("", MAX_ATTR_SIZE));
|
||||
attribute::create(badge_cluster, CONTACT_ATTRIBUTE_ID, ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_long_char_str("", MAX_ATTR_SIZE));
|
||||
attribute::create(badge_cluster, EMAIL_ATTRIBUTE_ID, ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_long_char_str("", MAX_ATTR_SIZE));
|
||||
attribute::create(badge_cluster, EVENT_NAME_ATTRIBUTE_ID, ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_long_char_str("", MAX_ATTR_SIZE));
|
||||
attribute::create(badge_cluster, COMPANY_NAME_ATTRIBUTE_ID, ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_long_char_str("", MAX_ATTR_SIZE));
|
||||
|
||||
uint32_t custom_command_id = 0x00;
|
||||
command::create(badge_cluster, custom_command_id, COMMAND_FLAG_ACCEPTED | COMMAND_FLAG_CUSTOM, update_badge_command_info);
|
||||
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
|
||||
/* Set OpenThread platform config */
|
||||
esp_openthread_platform_config_t config = {
|
||||
.radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(),
|
||||
.port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(),
|
||||
};
|
||||
set_openthread_platform_config(&config);
|
||||
#endif
|
||||
|
||||
/* Matter start */
|
||||
err = esp_matter::start(app_event_cb);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Matter start failed: %d", err);
|
||||
}
|
||||
|
||||
/* Starting driver with default values */
|
||||
if (chip::Server::GetInstance().GetFabricTable().FabricCount())
|
||||
app_driver_light_set_defaults(light_endpoint_id);
|
||||
|
||||
#if CONFIG_ENABLE_ENCRYPTED_OTA
|
||||
err = esp_matter_ota_requestor_encrypted_init(s_decryption_key, s_decryption_key_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to initialized the encrypted OTA, err: %d", err);
|
||||
}
|
||||
#endif // CONFIG_ENABLE_ENCRYPTED_OTA
|
||||
|
||||
#if CONFIG_ENABLE_CHIP_SHELL
|
||||
static const esp_matter::console::command_t change_name = {
|
||||
.name = "change_name",
|
||||
.description = "Change the name on badge",
|
||||
.handler = change_badge_name,
|
||||
};
|
||||
esp_matter::console::add_commands(&change_name, 1);
|
||||
|
||||
esp_matter::console::diagnostics_register_commands();
|
||||
esp_matter::console::wifi_register_commands();
|
||||
esp_matter::console::init();
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <esp_err.h>
|
||||
#include <esp_matter.h>
|
||||
|
||||
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
|
||||
#include "esp_openthread_types.h"
|
||||
#endif
|
||||
|
||||
#define BADGE_CLUSTER_ID 0x131BFC03
|
||||
|
||||
#define NAME_ATTRIBUTE_ID 0x0000
|
||||
#define COMPANY_NAME_ATTRIBUTE_ID 0x0001
|
||||
#define EMAIL_ATTRIBUTE_ID 0x0002
|
||||
#define CONTACT_ATTRIBUTE_ID 0x0003
|
||||
#define EVENT_NAME_ATTRIBUTE_ID 0x0004
|
||||
|
||||
#define MAX_ATTR_SIZE 33
|
||||
|
||||
#define DEFAULT_POWER true
|
||||
|
||||
typedef enum {
|
||||
NAME = 0,
|
||||
COMPANY_NAME,
|
||||
EMAIL,
|
||||
CONTACT,
|
||||
EVENT_NAME,
|
||||
MAX_VCARD_ATTR
|
||||
} vcard_tag;
|
||||
|
||||
extern bool badge_cluster_input_exists;
|
||||
|
||||
typedef void *app_driver_handle_t;
|
||||
|
||||
/** Initialize the button driver
|
||||
*
|
||||
* This initializes the button driver associated with the selected board.
|
||||
*
|
||||
* @return Handle on success.
|
||||
* @return NULL in case of failure.
|
||||
*/
|
||||
app_driver_handle_t app_driver_button_init();
|
||||
|
||||
/** Driver Update
|
||||
*
|
||||
* This API should be called to update the driver for the attribute being updated.
|
||||
* This is usually called from the common `app_attribute_update_cb()`.
|
||||
*
|
||||
* @param[in] endpoint_id Endpoint ID of the attribute.
|
||||
* @param[in] cluster_id Cluster ID of the attribute.
|
||||
* @param[in] attribute_id Attribute ID of the attribute.
|
||||
* @param[in] val Pointer to `esp_matter_attr_val_t`. Use appropriate elements as per the value type.
|
||||
*
|
||||
* @return ESP_OK on success.
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id,
|
||||
uint32_t attribute_id, esp_matter_attr_val_t *val);
|
||||
|
||||
/** Set defaults for light driver
|
||||
*
|
||||
* Set the attribute drivers to their default values from the created data model.
|
||||
*
|
||||
* @param[in] endpoint_id Endpoint ID of the driver.
|
||||
*
|
||||
* @return ESP_OK on success.
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t app_driver_light_set_defaults(uint16_t endpoint_id);
|
||||
|
||||
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
|
||||
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
|
||||
{ \
|
||||
.radio_mode = RADIO_MODE_NATIVE, \
|
||||
}
|
||||
|
||||
#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \
|
||||
{ \
|
||||
.host_connection_mode = HOST_CONNECTION_MODE_NONE, \
|
||||
}
|
||||
|
||||
#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \
|
||||
{ \
|
||||
.storage_partition_name = "ot_storage", .netif_queue_size = 10, .task_queue_size = 10, \
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
|
||||
esp_secure_cert, 0x3F, ,0xd000, 0x2000, encrypted
|
||||
nvs, data, nvs, 0x10000, 0xC000,
|
||||
nvs_keys, data, nvs_keys,, 0x1000, encrypted
|
||||
otadata, data, ota, , 0x2000
|
||||
phy_init, data, phy, , 0x1000,
|
||||
ota_0, app, ota_0, 0x20000, 0x1E0000,
|
||||
ota_1, app, ota_1, 0x200000, 0x1E0000,
|
||||
fctry, data, nvs, 0x3E0000, 0x6000
|
||||
|
@@ -0,0 +1,55 @@
|
||||
# Default to 921600 baud when flashing and monitoring device
|
||||
CONFIG_ESPTOOLPY_BAUD_921600B=y
|
||||
CONFIG_ESPTOOLPY_BAUD=921600
|
||||
CONFIG_ESPTOOLPY_COMPRESSED=y
|
||||
CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
|
||||
CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
|
||||
#enable BT
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_NIMBLE_ENABLED=y
|
||||
|
||||
#disable BT connection reattempt
|
||||
CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n
|
||||
|
||||
#enable lwip ipv6 autoconfig
|
||||
CONFIG_LWIP_IPV6_AUTOCONFIG=y
|
||||
|
||||
# Use a custom partition table
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0xC000
|
||||
|
||||
# Enable chip shell
|
||||
CONFIG_ENABLE_CHIP_SHELL=y
|
||||
|
||||
#enable lwIP route hooks
|
||||
CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y
|
||||
CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y
|
||||
|
||||
# Button
|
||||
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||
|
||||
# disable softap by default
|
||||
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
|
||||
|
||||
# Disable DS Peripheral
|
||||
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n
|
||||
|
||||
# Use compact attribute storage mode
|
||||
CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y
|
||||
|
||||
# Enable HKDF in mbedtls
|
||||
CONFIG_MBEDTLS_HKDF_C=y
|
||||
|
||||
# Increase LwIP IPv6 address number to 6 (MAX_FABRIC + 1)
|
||||
# unique local addresses for fabrics(MAX_FABRIC), a link local address(1)
|
||||
CONFIG_LWIP_IPV6_NUM_ADDRESSES=6
|
||||
|
||||
# SPI Configuration
|
||||
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
|
||||
CONFIG_SPI_SLAVE_ISR_IN_IRAM=n
|
||||
CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=n
|
||||
CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=n
|
||||
@@ -0,0 +1,81 @@
|
||||
## RainMaker Cluster
|
||||
|
||||
Attributes and commands for `Espressif Badge` User-Node Association.
|
||||
|
||||
|
||||
### 1. Revision History
|
||||
|
||||
The global ClusterRevision attribute value SHALL be the highest revision number in the table below.
|
||||
|
||||
| Revision | Description |
|
||||
|:--------:|:-------------------------------------:|
|
||||
| 1 | Initial cluster revision |
|
||||
|
||||
|
||||
### 2. Classification
|
||||
|
||||
| Hierarchy | Role | Scope |
|
||||
|:---------:|:-----------:|:--------:|
|
||||
|Base | Application | Endpoint |
|
||||
|
||||
|
||||
### 3. Cluster ID
|
||||
|
||||
| ID | Name |
|
||||
|:----------:|:--------------:|
|
||||
| 0x131BFC03 | EspressifBadge |
|
||||
|
||||
|
||||
### 4. Attributes
|
||||
|
||||
| ID | Name | Type | Constraint | Quality | Default | Access | Conformance |
|
||||
|:------:|:-----------------:|:------:|:----------:|:-------:|:-------:|:------:|:-----------:|
|
||||
| 0x0000 | Name | string | max 32 | | | RW | D |
|
||||
| 0x0001 | CompanyName | string | max 32 | | | RW | M |
|
||||
| 0x0002 | Email | string | max 32 | | | RW | M |
|
||||
| 0x0003 | Contact | string | max 32 | | | RW | M |
|
||||
| 0x0004 | EventName | string | max 32 | | | RW | M |
|
||||
|
||||
#### 4.1. Name Attribute
|
||||
|
||||
This attribute SHALL contain the name of the person wearing the badge.
|
||||
|
||||
#### 4.2. Company Name Attribute
|
||||
|
||||
This attribute SHALL contain the name of company of person wearing the badge.
|
||||
|
||||
#### 4.3. Email Attribute
|
||||
|
||||
This attribute SHALL contain Email.
|
||||
|
||||
#### 4.4. Contact Attribute
|
||||
|
||||
This attribute SHALL contain the contact number in the string format.
|
||||
|
||||
#### 4.5. Event Name Attribute
|
||||
|
||||
This attribute SHALL cotain the event name.
|
||||
|
||||
|
||||
### 5. Commands
|
||||
|
||||
| ID | Name | Direction | Response | Access | Conformance |
|
||||
|:----:|:-------------:|:---------------:|:--------:|:------:|:-----------:|
|
||||
| 0x00 | Configuration | client ⇒ server | Y | O | M |
|
||||
|
||||
#### 5.1. Configuration Command
|
||||
|
||||
This command instructs the badge to display the Name, CompanyName, Email, Contact and EventName on epaper display.
|
||||
- Prepare the command payload and <secret-key>
|
||||
|
||||
| ID | Name | Type | Constraint | Quality | Default | Access | Conformance |
|
||||
|:------:|:-----------------:|:------:|:----------:|:-------:|:-------:|:------:|:-----------:|
|
||||
| 0x0000 | Name | string | max 32 | | | RW | M |
|
||||
| 0x0001 | CompanyName | string | max 32 | | | RW | M |
|
||||
| 0x0002 | Email | string | max 32 | | | RW | M |
|
||||
| 0x0003 | Contact | string | max 32 | | | RW | M |
|
||||
| 0x0004 | EventName | string | max 32 | | | RW | M |
|
||||
|
||||
##### 5.1.1. Effect on Receipt
|
||||
|
||||
On receipt of Configuration command, a server SHALL set the attribute Name, CompanyName, Email, Contact and EventName. Additionally server SHALL display the Name, CompanyName, Email, Contact and EventName on epaper display.
|
||||