diff --git a/src/vendor/test/beep/CMakeLists.txt b/src/vendor/test/beep/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..9075d20e4b5f89f16f62e848829c50ec950d6214 --- /dev/null +++ b/src/vendor/test/beep/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/pwm_example.c" PARENT_SCOPE) \ No newline at end of file diff --git a/src/vendor/test/beep/README.md b/src/vendor/test/beep/README.md new file mode 100644 index 0000000000000000000000000000000000000000..36da708599268da05e7a60287eb0b2c80d024898 --- /dev/null +++ b/src/vendor/test/beep/README.md @@ -0,0 +1,114 @@ +# beep + +## 1.1 介绍 + +**功能介绍:** 使用PWM控制蜂鸣器鸣响。 + +**软件概述:** PWM是脉冲宽度调制缩写,通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比。 + +**硬件概述:** 核心板、交通灯板。通过板端丝印可以看出交通灯板的蜂鸣器BEEP与底板的A9相连,底板左边A9对应核心板GPIO 9。硬件搭建要求如图所示: + + 参考[核心板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf)、[交通灯板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_SSL_VER.A.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf) + + image-20240415144302434 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 蜂鸣器鸣响 + +## 1.4 接口介绍 + +#### 1.4.1 uapi_pwm_open() + +| **定义:** | errcode_t uapi_pwm_open(uint8_t channel, const pwm_config_t *cfg); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 打开具有指定配置的PWM设备 | +| **参数:** | channel:使用的pwm设备
cfg:PWM设备的配置信息 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pwm.h | + +#### 1.4.2 uapi_pwm_close() + +| 定义: | errcode_t uapi_pwm_close(uint8_t channel); | +| ------------ | ------------------------------------------ | +| **功能:** | 关闭指定的PWM。 | +| **参数:** | channel:使用的pwm设备 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pwm.h | + +#### 1.4.3 uapi_pwm_register_interrupt() + +| **定义:** | errcode_t uapi_pwm_register_interrupt(uint8_t channel, pwm_callback_t callback); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 为PWM注册中断回调 | +| **参数:** | channel:使用pwm设备
callback:回调函数 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pwm.h | + +#### 1.4.4 uapi_pwm_start() + +| **定义:** | errcode_t uapi_pwm_start(uint8_t channel); | +| ------------ | ------------------------------------------ | +| **功能:** | 开始PWM | +| **参数:** | channel:使用pwm设备 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pwm.h | + +#### 1.4.5 uapi_pwm_set_group() + +| **定义:** | errcode_t uapi_pwm_set_group(uint8_t group, uint16_t channel_id); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 为PWM通道分组 | +| **参数:** | group:PWM组
channel_id:分配到同一个组里的所有通道id,channel_id中的每一位bit对应相对应的一个通道 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pwm.h | + +## 1.5 具体实现 + + 步骤一:初始化PWM,配置PWM参数; + + 步骤二:打开指定PWM设备 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”beep“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\beep文件里面内容拷贝到**步骤一创建的Sample文件夹中”beep“**。 + + ![image-20240415150723600](../../../docs/pic/beep/image-20240415150723600.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support BEEP Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240415150847116 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七“软件烧录成功后,按一下开发板的RESET按键复位开发板,蜂鸣器会一直鸣响。 + + \ No newline at end of file diff --git a/src/vendor/test/beep/pwm_example.c b/src/vendor/test/beep/pwm_example.c new file mode 100644 index 0000000000000000000000000000000000000000..5bf5ab879eb52f8c0ec5cc8281a413573b0617bc --- /dev/null +++ b/src/vendor/test/beep/pwm_example.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "pwm.h" +#include "tcxo.h" +#include "soc_osal.h" +#include "app_init.h" + +#define PWM_CHANNEL 0 +#define PWM_GROUP_ID 0 +#define TEST_TCXO_DELAY_1000MS 1000 + +#define PWM_TASK_PRIO 24 +#define PWM_TASK_STACK_SIZE 0x1000 +#define CONFIG_PWM_PIN 9 +#define CONFIG_PWM_PIN_MODE 1 + +static errcode_t pwm_sample_callback(uint8_t channel) +{ + osal_printk("PWM %d, cycle done. \r\n", channel); + return ERRCODE_SUCC; +} + +static void *pwm_task(const char *arg) +{ + UNUSED(arg); + pwm_config_t cfg_no_repeat = {20000, + 10000, // 高电平持续tick 时间 = tick * (1/32000000) + 0, // 相位偏移位 + 1, // 发多少个波形 + true}; // 是否循环 + + uapi_pin_set_mode(CONFIG_PWM_PIN, CONFIG_PWM_PIN_MODE); + uapi_pwm_init(); + uapi_pwm_open(PWM_CHANNEL, &cfg_no_repeat); + uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); + uapi_pwm_unregister_interrupt(PWM_GROUP_ID); + uapi_pwm_register_interrupt(PWM_GROUP_ID, pwm_sample_callback); + uapi_pwm_set_group(PWM_GROUP_ID, 1 << PWM_CHANNEL); // 每个通道对应一个bit位 + uapi_pwm_start(PWM_GROUP_ID); + uapi_pwm_close(PWM_CHANNEL); // 波形发送完毕停止 + uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); + uapi_pwm_deinit(); + return NULL; +} + +static void pwm_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)pwm_task, 0, "PwmTask", PWM_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, PWM_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the pwm_entry. */ +app_run(pwm_entry); \ No newline at end of file diff --git a/src/vendor/test/buttondemo/CMakeLists.txt b/src/vendor/test/buttondemo/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a3e55cf619c756ba630c1998f47c98c9f55e74ce --- /dev/null +++ b/src/vendor/test/buttondemo/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/button_example.c" PARENT_SCOPE) diff --git a/src/vendor/test/buttondemo/README.md b/src/vendor/test/buttondemo/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5771b1d31c822b3e9bed6709c186b2dd900ac9ac --- /dev/null +++ b/src/vendor/test/buttondemo/README.md @@ -0,0 +1,107 @@ +# button + +## 1.1 介绍 + +**功能介绍:** 按键控制交通灯板上红色LED灯亮灭。 + +**软件概述:** GPIO引脚可以通过软件控制,使得CPU能够读取或写入GPIO引脚的电平值。而GPIO中断控制器则可以通过监测GPIO引脚的状态来检测外部设备的信号,这些信号可以触发中断请求,从而让CPU能够快速响应外部设备的事件。 + +**硬件概述:** 核心板、交通灯板。通过交通灯板上丝印可以看出是Switch与底板的MOSI相连,底板左边位置MOSI对应核心板上GPIO14。硬件搭建要求如图所示: + + 参考[核心板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf)、[交通灯板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_SSL_VER.A.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf) + + image-20240415144302434 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 通过交通灯板上的按键控制红色LED灯亮灭 + +## 1.4 接口介绍 + +#### 1.4.1 uapi_gpio_set_dir() + +| **定义:** | errcode_t uapi_gpio_set_dir(pin_t pin, gpio_direction_t dir); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置GPIO的输入输出方向函数 | +| **参数:** | pin: io引脚
dir:输入输出方向 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +#### 1.4.2 uapi_gpio_set_isr_mode() + +| 定义: | errcode_t uapi_gpio_set_isr_mode(pin_t pin, uint32_t trigger); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | HAL层GPIO设置中断模式 | +| **参数:** | pin:io引脚
tigger:GPIO中断类型:1 : 上升沿中断;2 : 下降沿中断;3 : 双边沿中断;4 : 低电平中断;8 : 高电平中断 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +#### 1.4.3 uapi_gpio_register_isr_func() + +| **定义:** | errcode_t uapi_gpio_register_isr_func(pin_t pin, uint32_t trigger, gpio_callback_t callback); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 注册GPIO的中断 | +| **参数:** | pin:io引脚
tigger:GPIO中断类型:1 : 上升沿中断;2 : 下降沿中断;3 : 双边沿中断;4 : 低电平中断;8 : 高电平中断
callback: 指向回调的指针 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +#### 1.4.4 uapi_gpio_enable_interrupt() + +| **定义:** | errcode_t uapi_gpio_enable_interrupt(pin_t pin); | +| ------------ | ------------------------------------------------ | +| **功能:** | 使能GPIO指定端口的中断 | +| **参数:** | pin:io引脚 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +## 1.5 具体实现 + + 步骤一:设置GPIO为输入模式; + + 步骤二:注册中断类型,中断函数等; + + 步骤三:根据中断类型不同,判断IO电平是否发生变化,实现按键功能 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”button“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\button文件里面内容拷贝到**步骤一创建的Sample文件夹中”button“**。 + +![image-20240415160249394](../../../docs/pic/button/image-20240415160249394.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support BUTTON Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240415160348940 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七“软件烧录成功后,按一下开发板的RESET按键复位开发板,可以通过交通灯板上的按键控制红色LED灯亮灭。 + + \ No newline at end of file diff --git a/src/vendor/test/buttondemo/button_example.c b/src/vendor/test/buttondemo/button_example.c new file mode 100644 index 0000000000000000000000000000000000000000..a4529f834710336d4dbc7f1182eaafc1039b921b --- /dev/null +++ b/src/vendor/test/buttondemo/button_example.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "common_def.h" +#include "soc_osal.h" +#include "gpio.h" +#include "hal_gpio.h" +#include "test_suite_log.h" +#include "watchdog.h" +#include "app_init.h" + +#define BSP_LED 7 // RED +#define BUTTON_GPIO 12 // 按键 +#define GPIO5_MODE 0 +#define BUTTON_TASK_STACK_SIZE 0x1000 +#define BUTTON_TASK_PRIO 17 + +static int g_ledState = 0; + +static void gpio_callback_func(pin_t pin, uintptr_t param) +{ + UNUSED(pin); + UNUSED(param); + g_ledState = !g_ledState; + printf("Button pressed.\r\n"); +} + +static void *button_task(const char *arg) +{ + unused(arg); + uapi_pin_set_mode(BSP_LED, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(BSP_LED, GPIO_DIRECTION_OUTPUT); + uapi_gpio_set_val(BSP_LED, GPIO_LEVEL_LOW); + uapi_pin_set_mode(BUTTON_GPIO, HAL_PIO_FUNC_GPIO); + gpio_select_core(BUTTON_GPIO, CORES_APPS_CORE); + uapi_gpio_set_dir(BUTTON_GPIO, GPIO_DIRECTION_INPUT); + errcode_t ret = uapi_gpio_register_isr_func(BUTTON_GPIO, GPIO_INTERRUPT_FALLING_EDGE, gpio_callback_func); + if (ret != 0) { + uapi_gpio_unregister_isr_func(BUTTON_GPIO); + } + while (1) { + uapi_watchdog_kick(); // 喂狗,防止程序出现异常系统挂死 + if (g_ledState) { + uapi_gpio_set_val(BSP_LED, GPIO_LEVEL_HIGH); + } else { + uapi_gpio_set_val(BSP_LED, GPIO_LEVEL_LOW); + } + } + return NULL; +} + +static void button_entry(void) +{ + uint32_t ret; + osal_task *taskid; + // 创建任务调度 + osal_kthread_lock(); + // 创建任务1 + taskid = osal_kthread_create((osal_kthread_handler)button_task, NULL, "led_task", BUTTON_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid, BUTTON_TASK_PRIO); + if (ret != OSAL_SUCCESS) { + printf("create task1 failed .\n"); + } + osal_kthread_unlock(); +} + +/* Run the blinky_entry. */ +app_run(button_entry); \ No newline at end of file diff --git a/src/vendor/test/environment/CMakeLists.txt b/src/vendor/test/environment/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4ae834eb0975cd37a86c44a3d4afa4a99775f5a4 --- /dev/null +++ b/src/vendor/test/environment/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/aht20.c" "${CMAKE_CURRENT_SOURCE_DIR}/aht20_test.c" "${CMAKE_CURRENT_SOURCE_DIR}/ssd1306_fonts.c" "${CMAKE_CURRENT_SOURCE_DIR}/ssd1306.c" PARENT_SCOPE) diff --git a/src/vendor/test/environment/README.md b/src/vendor/test/environment/README.md new file mode 100644 index 0000000000000000000000000000000000000000..72059d53f4b56f39f96dfeea3e5b37cb7ff18049 --- /dev/null +++ b/src/vendor/test/environment/README.md @@ -0,0 +1,136 @@ +# environment + +## 1.1 介绍 + +**功能介绍:** 在SSD1306 OLED屏幕实时显示当前环境温湿度。 + +**软件概述:** I2C是一种串行通信协议,允许将多个设备连接到一条总线上。每个连接到总线上的器件都有唯一地址,任何器件既可作为主机也可以作为从机,但同一时刻只允许有一个主机。 + +**硬件概述:** 核心板、OLED板,OLED数据手册参考:https://gitee.com/HiSpark/hi3861_hdu_iot_application/issues/I6WPSS?from=project-issue 里面的液晶显示器.pdf。 通过OLED板原理图可以看出OLED板SDA与底板TX、SCL与底板RX,底板左边TX对应核心板TXD1,底板左边RX对应核心板RXD1;环境监测板AHT20数据手册参考https://gitee.com/HiSpark/hi3861_hdu_iot_application/issues/I6WPSS?from=project-issue 里面的AHT20.pdf,通过环境监测板原理图可以看出环境监测板板SDA与底板TX、SCL与底板RX,底板左边TX对应核心板TXD1,底板左边RX对应核心板RXD1;硬件搭建要求如图所示: + + 参考[核心板板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf)、[OLED板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_OLED_VER.A.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf)、[环境监测原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EM_VER.A.pdf) + + image-20240205100955110 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.T100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 板上小屏幕实时显示环境温度和湿度。 + + ![image-20240205110527741](../../../docs/pic/environment/image-20240205110527741.png) + +## 1.4 接口介绍 + +### 1.4.1 uapi_i2c_master_read() + +| **定义:** | errcode_t uapi_i2c_master_read(i2c_bus_t bus, uint16_t dev_addr, i2c_data_t *data); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 主机接收来自目标I2C从机的数据,有两种方式,一种是手动切换方式,另外一种是自动切换模式,两种方式静态配置,手动切换方式一共有以下三种传输模式,但是不能在同一bus中同时使用 | +| **参数:** | bus:I2C总线
dev_addr:主机接收数据的目标从机地址
data:接收数据的数据指针 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\i2c.h | + +### 1.4.2 uapi_i2c_master_write() + +| 定义: | errcode_t uapi_i2c_master_write(i2c_bus_t bus, uint16_t dev_addr, i2c_data_t *data); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 将数据从主机写入到从机,有两种方式,一种是手动切换方式,另外一种是自动切换模式,两种方式静态配置,手动切换方式一共有以下三种传输模式,但是不能在同一bus中同时使用 | +| **参数:** | bus:I2C总线
dev_addr:主机接收数据的目标从机地址
data:发送数据的数据指针 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\i2c.h | + +### 1.4.3 uapi_i2c_master_init() + +| **定义:** | errcode_t uapi_i2c_master_init(i2c_bus_t bus, uint32_t baudrate, uint8_t hscode); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 根据指定的参数初始化该i2c为主机 | +| **参数:** | bus:I2C总线
baudrate:i2c波特率
hscode:i2c高速模式主机码,每个主机有自己唯一的主机码,有效取值范围0~7,仅在高速模式下需要配置 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\i2c.h | + +### 1.4.4 uapi_pin_set_mode() + +| **定义:** | errcode_t uapi_pin_set_mode(pin_t pin, pin_mode_t mode); | +| ------------ | -------------------------------------------------------- | +| **功能:** | 设置引脚复用模式 | +| **参数:** | pin:io
mode:复用模式 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pinctrl.h | + +### 1.4.5 ssd1306_SetCursor() + +| **定义:** | void ssd1306_SetCursor(uint8_t x, uint8_t y); | +| ------------ | --------------------------------------------- | +| **功能:** | 设置字符串显示位置 | +| **参数:** | x:横坐标
y:众坐标 | +| **返回值:** | 无返回值 | +| **依赖:** | oled\ssd1306.h | + +### 1.4.6 ssd1306_DrawString() + +| **定义:** | char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置输出的字符串 | +| **参数:** | str:要输出的字符串
Font:字符串大小
color:颜色 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | oled\ssd1306.h | + +### 1.4.7 ssd1306_UpdateScreen() + +| **定义:** | void ssd1306_UpdateScreen(void); | +| ------------ | -------------------------------- | +| **功能:** | 在屏幕显示字符串 | +| **参数:** | 无 | +| **返回值:** | 无 | +| **依赖:** | oled\ssd1306.h | + +## 1.5 具体实现 + + 步骤一:初始化I2C设备; + + 步骤二:I2C通信正常后,初始化OLED; + + 步骤三:通过数据手册中协议要求,发送数据 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”environment“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\environment文件里面内容拷贝到**步骤一创建的Sample文件夹中”environment“**。 + + ![image-20240417175458664](../../../docs/pic/environment/image-20240417175458664.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support ENVIRONMENT Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240417175558457 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七“软件烧录成功后,按一下开发板的RESET按键复位开发板,板上小屏幕实时显示环境温度和湿度。 + + ![image-20240205110527741](../../../docs/pic/environment/image-20240205110527741.png) \ No newline at end of file diff --git a/src/vendor/test/environment/aht20.c b/src/vendor/test/environment/aht20.c new file mode 100644 index 0000000000000000000000000000000000000000..d3a5e0909c82411f90d72668ea3640d61bd889b9 --- /dev/null +++ b/src/vendor/test/environment/aht20.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "i2c.h" +#include "osal_debug.h" +#include "cmsis_os2.h" +// #include "app_init.h" +#include "aht20.h" + +#define AHT20_STARTUP_TIME (20 * 10) // 上电启动时间 +#define AHT20_CALIBRATION_TIME (40 * 10) // 初始化(校准)时间 +#define AHT20_MEASURE_TIME (75 * 10) // 测量时间 + +#define AHT20_DEVICE_ADDR 0x38 +#define AHT20_READ_ADDR ((0x38 << 1) | 0x1) +#define AHT20_WRITE_ADDR ((0x38 << 1) | 0x0) + +#define AHT20_CMD_CALIBRATION 0xBE // 初始化(校准)命令 +#define AHT20_CMD_CALIBRATION_ARG0 0x08 +#define AHT20_CMD_CALIBRATION_ARG1 0x00 + +/** + * 传感器在采集时需要时间,主机发出测量指令(0xAC)后,延时75毫秒以上再读取转换后的数据并判断返回的状态位是否正常。 + * 若状态比特位[Bit7]为0代表数据可正常读取,为1时传感器为忙状态,主机需要等待数据处理完成。 + **/ +#define AHT20_CMD_TRIGGER 0xAC // 触发测量命令 +#define AHT20_CMD_TRIGGER_ARG0 0x33 +#define AHT20_CMD_TRIGGER_ARG1 0x00 + +// 用于在无需关闭和再次打开电源的情况下,重新启动传感器系统,软复位所需时间不超过20 毫秒 +#define AHT20_CMD_RESET 0xBA // 软复位命令 + +#define AHT20_CMD_STATUS 0x71 // 获取状态命令 + +/** + * STATUS 命令回复: + * 1. 初始化后触发测量之前,STATUS 只回复 1B 状态值; + * 2. 触发测量之后,STATUS 回复6B: 1B 状态值 + 2B 湿度 + 4b湿度 + 4b温度 + 2B 温度 + * RH = Srh / 2^20 * 100% + * T = St / 2^20 * 200 - 50 + **/ +#define AHT20_STATUS_BUSY_SHIFT 7 // bit[7] Busy indication +#define AHT20_STATUS_BUSY_MASK (0x1 << AHT20_STATUS_BUSY_SHIFT) + +#define AHT20_STATUS_MODE_SHIFT 5 // bit[6:5] Mode Status +#define AHT20_STATUS_MODE_MASK (0x3 << AHT20_STATUS_MODE_SHIFT) + +// bit[4] Reserved +#define AHT20_STATUS_CALI_SHIFT 3 // bit[3] CAL Enable +#define AHT20_STATUS_CALI_MASK (0x1 << AHT20_STATUS_CALI_SHIFT) // bit[2:0] Reserved + +#define AHT20_STATUS_RESPONSE_MAX 6 + +#define AHT20_RESLUTION (1 << 20) // 2^20 + +#define AHT20_MAX_RETRY 10 +#define CONFIG_I2C_MASTER_BUS_ID 1 +#define I2C_SLAVE1_ADDR 0x38 + +uint8_t aht20_status_busy(uint8_t status) +{ + return ((status & AHT20_STATUS_BUSY_MASK) >> (AHT20_STATUS_BUSY_SHIFT)); +} + +uint8_t aht20_status_mode(uint8_t status) +{ + return ((status & AHT20_STATUS_MODE_MASK) >> (AHT20_STATUS_MODE_SHIFT)); +} + +uint8_t aht20_status_cali(uint8_t status) +{ + return ((status & AHT20_STATUS_CALI_MASK) >> (AHT20_STATUS_CALI_SHIFT)); +} + +static uint32_t AHT20_Read(uint8_t *buffer, uint32_t buffLen) +{ + uint16_t dev_addr = AHT20_DEVICE_ADDR; + i2c_data_t data = {0}; + data.receive_buf = buffer; + data.receive_len = buffLen; + uint32_t retval = uapi_i2c_master_read(CONFIG_I2C_MASTER_BUS_ID, dev_addr, &data); + if (retval != 0) { + printf("I2cRead() failed, %0X!\n", retval); + return retval; + } + return 0; +} + +static uint32_t AHT20_Write(uint8_t *buffer, uint32_t buffLen) +{ + uint16_t dev_addr = AHT20_DEVICE_ADDR; + i2c_data_t data = {0}; + data.send_buf = buffer; + data.send_len = buffLen; + uint32_t retval = uapi_i2c_master_write(CONFIG_I2C_MASTER_BUS_ID, dev_addr, &data); + if (retval != 0) { + printf("I2cWrite(%02X) failed, %0X!\n", buffer[0], retval); + return retval; + } + return 0; +} + +// 发送获取状态命令 +static uint32_t AHT20_StatusCommand(void) +{ + uint8_t statusCmd[] = {AHT20_CMD_STATUS}; + return AHT20_Write(statusCmd, sizeof(statusCmd)); +} + +// 发送软复位命令 +static uint32_t AHT20_ResetCommand(void) +{ + uint8_t resetCmd[] = {AHT20_CMD_RESET}; + return AHT20_Write(resetCmd, sizeof(resetCmd)); +} + +// 发送初始化校准命令 +static uint32_t AHT20_CalibrateCommand(void) +{ + uint8_t clibrateCmd[] = {AHT20_CMD_CALIBRATION, AHT20_CMD_CALIBRATION_ARG0, AHT20_CMD_CALIBRATION_ARG1}; + return AHT20_Write(clibrateCmd, sizeof(clibrateCmd)); +} + +// 读取温湿度值之前, 首先要看状态字的校准使能位Bit[3]是否为 1(通过发送0x71可以获取一个字节的状态字), +// 如果不为1,要发送0xBE命令(初始化),此命令参数有两个字节, 第一个字节为0x08,第二个字节为0x00。 +uint32_t AHT20_Calibrate(void) +{ + uint32_t retval = 0; + uint8_t buffer[AHT20_STATUS_RESPONSE_MAX] = {AHT20_CMD_STATUS}; + memset_s(&buffer, sizeof(buffer), 0x0, sizeof(buffer)); + retval = AHT20_StatusCommand(); + if (retval != 0) { + return retval; + } + + retval = AHT20_Read(buffer, sizeof(buffer)); + if (retval != 0) { + return retval; + } + + if (aht20_status_busy(buffer[0]) || !aht20_status_cali(buffer[0])) { + retval = AHT20_ResetCommand(); + if (retval != 0) { + return retval; + } + osDelay(AHT20_STARTUP_TIME); + retval = AHT20_CalibrateCommand(); + osDelay(AHT20_CALIBRATION_TIME); + return retval; + } + return 0; +} + +// 发送 触发测量 命令,开始测量 +uint32_t AHT20_StartMeasure(void) +{ + uint8_t triggerCmd[] = {AHT20_CMD_TRIGGER, AHT20_CMD_TRIGGER_ARG0, AHT20_CMD_TRIGGER_ARG1}; + return AHT20_Write(triggerCmd, sizeof(triggerCmd)); +} + +// 接收测量结果,拼接转换为标准值 +uint32_t AHT20_GetMeasureResult(float *temp, float *humi) +{ + uint32_t retval = 0, i = 0; + if (temp == NULL || humi == NULL) { + return 0; + } + + uint8_t buffer[AHT20_STATUS_RESPONSE_MAX] = {0}; + memset_s(&buffer, sizeof(buffer), 0x0, sizeof(buffer)); + retval = AHT20_Read(buffer, sizeof(buffer)); // recv status command result + if (retval != 0) { + return retval; + } + + for (i = 0; aht20_status_busy(buffer[0]) && i < AHT20_MAX_RETRY; i++) { + osDelay(10); + retval = AHT20_Read(buffer, sizeof(buffer)); // recv status command result + if (retval != 0) { + return retval; + } + } + if (i >= AHT20_MAX_RETRY) { + printf("AHT20 device always busy!\r\n"); + return 0; + } + + uint32_t humiRaw = buffer[1]; + humiRaw = (humiRaw << 8) | buffer[2]; // 左移8位或buff[2]得到数据,具体可以看芯片手册 + humiRaw = (humiRaw << 4) | ((buffer[3] & 0xF0) >> 4); // 左移4位或buff[3]得到数据,具体可以看芯片手册 + *humi = humiRaw / (float)AHT20_RESLUTION * 100; // 100量程 + + uint32_t tempRaw = buffer[3] & 0x0F; + tempRaw = (tempRaw << 8) | buffer[4]; /* 左移8位或buff[4]得到数据,具体可以看芯片手册 */ + tempRaw = (tempRaw << 8) | buffer[5]; // 左移8位或buff[5]得到数据,具体可以看芯片手册 + *temp = tempRaw / (float)AHT20_RESLUTION * 200 - 50; /* 200 50量程 */ + return 0; +} \ No newline at end of file diff --git a/src/vendor/test/environment/aht20.h b/src/vendor/test/environment/aht20.h new file mode 100644 index 0000000000000000000000000000000000000000..6b4d163693cd213132a9c548650a9662d0b7a7da --- /dev/null +++ b/src/vendor/test/environment/aht20.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 AHT20_H +#define AHT20_H + +#include + +uint32_t AHT20_Calibrate(void); + +uint32_t AHT20_StartMeasure(void); + +uint32_t AHT20_GetMeasureResult(float *temp, float *humi); + +#endif // AHT20_H \ No newline at end of file diff --git a/src/vendor/test/environment/aht20_test.c b/src/vendor/test/environment/aht20_test.c new file mode 100644 index 0000000000000000000000000000000000000000..b36bd1246183a111ab59bbd4f2df7549852e1944 --- /dev/null +++ b/src/vendor/test/environment/aht20_test.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "i2c.h" +#include "osal_debug.h" +#include "ssd1306_fonts.h" +#include "ssd1306.h" +#include "soc_osal.h" +#include "aht20.h" +#include "app_init.h" + +#define CONFIG_I2C_SCL_MASTER_PIN 15 +#define CONFIG_I2C_SDA_MASTER_PIN 16 +#define CONFIG_I2C_MASTER_PIN_MODE 2 +#define I2C_MASTER_ADDR 0x0 +#define I2C_SLAVE1_ADDR 0x38 +#define I2C_SET_BANDRATE 400000 +#define I2C_TASK_STACK_SIZE 0x1000 +#define I2C_TASK_PRIO 17 + +const unsigned char headSize[] = {64, 64}; + +void app_i2c_init_pin(void) +{ + uapi_pin_set_mode(CONFIG_I2C_SCL_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_I2C_SDA_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE); +} + +/** + * 汉字字模在线: https://www.23bei.com/tool-223.html + * 数据排列:从左到右从上到下 + * 取模方式:横向8位左高位 + * 字体总类:[HZK1616宋体] + **/ +void TempHumChinese(void) +{ + const uint32_t W = 16; + uint8_t fonts[][32] = { + {/* -- ID:0,字符:"温",ASCII编码:CEC2,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节 */ + 0x00, 0x08, 0x43, 0xFC, 0x32, 0x08, 0x12, 0x08, 0x83, 0xF8, 0x62, 0x08, 0x22, 0x08, 0x0B, 0xF8, + 0x10, 0x00, 0x27, 0xFC, 0xE4, 0xA4, 0x24, 0xA4, 0x24, 0xA4, 0x24, 0xA4, 0x2F, 0xFE, 0x20, 0x00}, + {/* -- ID:0,字符:"度",ASCII编码:B6C8,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节 */ + 0x01, 0x00, 0x00, 0x84, 0x3F, 0xFE, 0x22, 0x20, 0x22, 0x28, 0x3F, 0xFC, 0x22, 0x20, 0x23, 0xE0, + 0x20, 0x00, 0x2F, 0xF0, 0x22, 0x20, 0x21, 0x40, 0x20, 0x80, 0x43, 0x60, 0x8C, 0x1E, 0x30, 0x04}}; + uint8_t fonts2[][32] = { + {/* -- ID:0,字符:"湿",ASCII编码:CEC2,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节 */ + 0x00, 0x08, 0x47, 0xFC, 0x34, 0x08, 0x14, 0x08, 0x87, 0xF8, 0x64, 0x08, 0x24, 0x08, 0x0F, 0xF8, + 0x11, 0x20, 0x21, 0x20, 0xE9, 0x24, 0x25, 0x28, 0x23, 0x30, 0x21, 0x24, 0x3F, 0xFE, 0x20, 0x00}, + {/* -- ID:0,字符:"度",ASCII编码:B6C8,对应字:宽x高=16x16,画布:宽W=16 高H=16,共32字节 */ + 0x01, 0x00, 0x00, 0x84, 0x3F, 0xFE, 0x22, 0x20, 0x22, 0x28, 0x3F, 0xFC, 0x22, 0x20, 0x23, 0xE0, + 0x20, 0x00, 0x2F, 0xF0, 0x22, 0x20, 0x21, 0x40, 0x20, 0x80, 0x43, 0x60, 0x8C, 0x1E, 0x30, 0x04}}; + for (size_t i = 0; i < sizeof(fonts) / sizeof(fonts[0]); i++) { + ssd1306_DrawRegion(i * W, 3, W, fonts[i], sizeof(fonts[0])); // x轴坐标i*w,y轴坐标3,宽度为16 + } + for (size_t j = 0; j < sizeof(fonts2) / sizeof(fonts2[0]); j++) { + ssd1306_DrawRegion(j * W, 35, W, fonts2[j], sizeof(fonts2[0])); // x轴坐标i*w,y轴坐标35,宽度为16 + } +} + +void Aht20TestTask(void) +{ + uint32_t retval = 0; + float temp = 0.0f; + float humi = 0.0f; + static char templine[32] = {0}; + static char humiline[32] = {0}; + uint32_t baudrate = I2C_SET_BANDRATE; + uint32_t hscode = I2C_MASTER_ADDR; + app_i2c_init_pin(); + errcode_t ret = uapi_i2c_master_init(1, baudrate, hscode); + if (ret != 0) { + printf("i2c init failed, ret = %0x\r\n", ret); + } + ssd1306_Init(); + ssd1306_Fill(Black); + ssd1306_SetCursor(0, 0); + while (AHT20_Calibrate() != 0) { + printf("AHT20 sensor init failed!\r\n"); + osal_mdelay(100); // 10ms在判断设备是否复位成功 + } + while (1) { + TempHumChinese(); + retval = AHT20_StartMeasure(); + printf("AHT20_StartMeasure: %d\r\n", retval); + retval = AHT20_GetMeasureResult(&temp, &humi); + if (retval != 0) { + printf("get humidity data failed!\r\n"); + } + ssd1306_SetCursor(32, 8); /* x坐标为32,y轴坐标为8 */ + int ret = sprintf(templine, ": %.2f", temp); + if (ret < 0) { + printf("temp failed\r\n"); + } + ssd1306_DrawString(templine, Font_7x10, White); + ret = sprintf(humiline, ": %.2f", humi); + if (ret < 0) { + printf("humi failed\r\n"); + } + printf("temp = %s, humi = %s\r\n", templine, humiline); + ssd1306_SetCursor(32, 40); /* x坐标为32,y轴坐标为40 */ + ssd1306_DrawString(humiline, Font_7x10, White); + ssd1306_UpdateScreen(); + osal_mdelay(1000); // 1s监测一次 + } +} + +void Aht20Test(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)Aht20TestTask, 0, "PwmTask", I2C_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, I2C_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +app_run(Aht20Test); \ No newline at end of file diff --git a/src/vendor/test/environment/aht20_test.h b/src/vendor/test/environment/aht20_test.h new file mode 100644 index 0000000000000000000000000000000000000000..53e392232d869278de9d602ace281341ffbf5826 --- /dev/null +++ b/src/vendor/test/environment/aht20_test.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 AHT20_TEST_H +#define AHT20_TEST_H + +void Aht20TestTask(void); + +#endif // AHT20_H \ No newline at end of file diff --git a/src/vendor/test/environment/ssd1306.c b/src/vendor/test/environment/ssd1306.c new file mode 100644 index 0000000000000000000000000000000000000000..e7c4dab13006eb2a6cfd7513fa37f76b2489776e --- /dev/null +++ b/src/vendor/test/environment/ssd1306.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 +#include +#include +#include +#include +#include +#include +#include "i2c.h" +#include "soc_osal.h" +#include "ssd1306.h" + +#define CONFIG_I2C_MASTER_BUS_ID 1 +#define I2C_SLAVE2_ADDR 0x3C +#define SSD1306_CTRL_CMD 0x00 +#define SSD1306_CTRL_DATA 0x40 +#define SSD1306_MASK_CONT (0x1 << 7) +#define DOUBLE 2 + +void ssd1306_Reset(void) +{ + // Wait for the screen to boot,1ms The delay here is very important + osal_mdelay(1); +} + +static uint32_t ssd1306_SendData(uint8_t *buffer, uint32_t size) +{ + uint16_t dev_addr = I2C_SLAVE2_ADDR; + i2c_data_t data = {0}; + data.send_buf = buffer; + data.send_len = size; + uint32_t retval = uapi_i2c_master_write(CONFIG_I2C_MASTER_BUS_ID, dev_addr, &data); + if (retval != 0) { + printf("I2cWrite(%02X) failed, %0X!\n", data.send_buf[1], retval); + return retval; + } + return 0; +} + +static uint32_t ssd1306_WiteByte(uint8_t regAddr, uint8_t byte) +{ + uint8_t buffer[] = {regAddr, byte}; + return ssd1306_SendData(buffer, sizeof(buffer)); +} + +// Send a byte to the command register +void ssd1306_WriteCommand(uint8_t byte) +{ + ssd1306_WiteByte(SSD1306_CTRL_CMD, byte); +} + +// Send data +void ssd1306_WriteData(uint8_t *buffer, uint32_t buff_size) +{ + uint8_t data[SSD1306_WIDTH * DOUBLE] = {0}; + for (uint32_t i = 0; i < buff_size; i++) { + data[i * DOUBLE] = SSD1306_CTRL_DATA | SSD1306_MASK_CONT; + data[i * DOUBLE + 1] = buffer[i]; + } + data[(buff_size - 1) * DOUBLE] = SSD1306_CTRL_DATA; + ssd1306_SendData(data, sizeof(data)); +} + +// Screenbuffer +static uint8_t SSD1306_Buffer[SSD1306_BUFFER_SIZE]; + +// Screen object +static SSD1306_t SSD1306; + +/* Fills the Screenbuffer with values from a given buffer of a fixed length */ +SSD1306_Error_t ssd1306_FillBuffer(uint8_t *buf, uint32_t len) +{ + SSD1306_Error_t ret = SSD1306_ERR; + if (len <= SSD1306_BUFFER_SIZE) { + memcpy_s(SSD1306_Buffer, len + 1, buf, len); + ret = SSD1306_OK; + } + return ret; +} + +void ssd1306_Init_CMD(void) +{ + ssd1306_WriteCommand(0xA4); // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content + + ssd1306_WriteCommand(0xD3); // -set display offset - CHECK + ssd1306_WriteCommand(0x00); // -not offset + + ssd1306_WriteCommand(0xD5); // --set display clock divide ratio/oscillator frequency + ssd1306_WriteCommand(0xF0); // --set divide ratio + + ssd1306_WriteCommand(0xD9); // --set pre-charge period + ssd1306_WriteCommand(0x11); // 0x22 by default + + ssd1306_WriteCommand(0xDA); // --set com pins hardware configuration - CHECK +#if (SSD1306_HEIGHT == 32) + ssd1306_WriteCommand(0x02); +#elif (SSD1306_HEIGHT == 64) + ssd1306_WriteCommand(0x12); +#elif (SSD1306_HEIGHT == 128) + ssd1306_WriteCommand(0x12); +#else +#error "Only 32, 64, or 128 lines of height are supported!" +#endif + + ssd1306_WriteCommand(0xDB); // --set vcomh + ssd1306_WriteCommand(0x30); // 0x20,0.77xVcc, 0x30,0.83xVcc + + ssd1306_WriteCommand(0x8D); // --set DC-DC enable + ssd1306_WriteCommand(0x14); // + ssd1306_SetDisplayOn(1); // --turn on SSD1306 panel +} + +// Initialize the oled screen +void ssd1306_Init(void) +{ + // Reset OLED + ssd1306_Reset(); + // Init OLED + ssd1306_SetDisplayOn(0); // display off + + ssd1306_WriteCommand(0x20); // Set Memory Addressing Mode + ssd1306_WriteCommand(0x00); // 00b,Horizontal Addressing Mode; 01b,Vertical Addressing Mode; + // 10b,Page Addressing Mode (RESET); 11b,Invalid + + ssd1306_WriteCommand(0xB0); // Set Page Start Address for Page Addressing Mode,0-7 + +#ifdef SSD1306_MIRROR_VERT + ssd1306_WriteCommand(0xC0); // Mirror vertically +#else + ssd1306_WriteCommand(0xC8); // Set COM Output Scan Direction +#endif + + ssd1306_WriteCommand(0x00); // ---set low column address + ssd1306_WriteCommand(0x10); // ---set high column address + + ssd1306_WriteCommand(0x40); // --set start line address - CHECK + + ssd1306_SetContrast(0xFF); + +#ifdef SSD1306_MIRROR_HORIZ + ssd1306_WriteCommand(0xA0); // Mirror horizontally +#else + ssd1306_WriteCommand(0xA1); // --set segment re-map 0 to 127 - CHECK +#endif + +#ifdef SSD1306_INVERSE_COLOR + ssd1306_WriteCommand(0xA7); // --set inverse color +#else + ssd1306_WriteCommand(0xA6); // --set normal color +#endif + +// Set multiplex ratio. +#if (SSD1306_HEIGHT == 128) + // Found in the Luma Python lib for SH1106. + ssd1306_WriteCommand(0xFF); +#else + ssd1306_WriteCommand(0xA8); // --set multiplex ratio(1 to 64) - CHECK +#endif + +#if (SSD1306_HEIGHT == 32) + ssd1306_WriteCommand(0x1F); // +#elif (SSD1306_HEIGHT == 64) + ssd1306_WriteCommand(0x3F); // +#elif (SSD1306_HEIGHT == 128) + ssd1306_WriteCommand(0x3F); // Seems to work for 128px high displays too. +#else +#error "Only 32, 64, or 128 lines of height are supported!" +#endif + ssd1306_Init_CMD(); + // Clear screen + ssd1306_Fill(Black); + + // Flush buffer to screen + ssd1306_UpdateScreen(); + + // Set default values for screen object + SSD1306.CurrentX = 0; + SSD1306.CurrentY = 0; + + SSD1306.Initialized = 1; +} + +// Fill the whole screen with the given color +void ssd1306_Fill(SSD1306_COLOR color) +{ + /* Set memory */ + uint32_t i; + + for (i = 0; i < sizeof(SSD1306_Buffer); i++) { + SSD1306_Buffer[i] = (color == Black) ? 0x00 : 0xFF; + } +} + +// Write the screenbuffer with changed to the screen +void ssd1306_UpdateScreen(void) +{ + // Write data to each page of RAM. Number of pages + // depends on the screen height: + // + // * 32px == 4 pages + // * 64px == 8 pages + // * 128px == 16 pages + + uint8_t cmd[] = { + 0X21, // 设置列起始和结束地址 + 0X00, // 列起始地址 0 + 0X7F, // 列终止地址 127 + 0X22, // 设置页起始和结束地址 + 0X00, // 页起始地址 0 + 0X07, // 页终止地址 7 + }; + uint32_t count = 0; + uint8_t data[sizeof(cmd) * DOUBLE + SSD1306_BUFFER_SIZE + 1] = {}; + + // copy cmd + for (uint32_t i = 0; i < sizeof(cmd) / sizeof(cmd[0]); i++) { + data[count++] = SSD1306_CTRL_CMD | SSD1306_MASK_CONT; + data[count++] = cmd[i]; + } + + // copy frame data + data[count++] = SSD1306_CTRL_DATA; + memcpy_s(&data[count], SSD1306_BUFFER_SIZE + 1, SSD1306_Buffer, SSD1306_BUFFER_SIZE); + count += sizeof(SSD1306_Buffer); + + // send to i2c bus + uint32_t retval = ssd1306_SendData(data, count); + if (retval != 0) { + printf("ssd1306_UpdateScreen send frame data filed: %d!\r\n", retval); + } +} + +// Draw one pixel in the screenbuffer +// X => X Coordinate +// Y => Y Coordinate +// color => Pixel color +void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color) +{ + if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) { + // Don't write outside the buffer + return; + } + SSD1306_COLOR color1 = color; + // Check if pixel should be inverted + if (SSD1306.Inverted) { + color1 = (SSD1306_COLOR)!color1; + } + + // Draw in the right color + uint32_t c = 8; // 8 + if (color == White) { + SSD1306_Buffer[x + (y / c) * SSD1306_WIDTH] |= 1 << (y % c); + } else { + SSD1306_Buffer[x + (y / c) * SSD1306_WIDTH] &= ~(1 << (y % c)); + } +} + +// Draw 1 char to the screen buffer +// ch => char om weg te schrijven +// Font => Font waarmee we gaan schrijven +// color => Black or White +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color) +{ + uint32_t i, b, j; + + // Check if character is valid + uint32_t ch_min = 32; // 32 + uint32_t ch_max = 126; // 126 + if ((uint32_t)ch < ch_min || (uint32_t)ch > ch_max) { + return 0; + } + + // Check remaining space on current line + if (SSD1306_WIDTH < (SSD1306.CurrentX + Font.FontWidth) || SSD1306_HEIGHT < (SSD1306.CurrentY + Font.FontHeight)) { + // Not enough space on current line + return 0; + } + + // Use the font to write + for (i = 0; i < Font.FontHeight; i++) { + b = Font.data[(ch - ch_min) * Font.FontHeight + i]; + for (j = 0; j < Font.FontWidth; j++) { + if ((b << j) & 0x8000) { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)color); + } else { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color); + } + } + } + + // The current space is now taken + SSD1306.CurrentX += Font.FontWidth; + + // Return written char for validation + return ch; +} + +// Write full string to screenbuffer +char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color) +{ + // Write until null-byte + char *str1 = str; + while (*str1) { + if (ssd1306_DrawChar(*str1, Font, color) != *str1) { + // Char could not be written + return *str1; + } + // Next char + str1++; + } + + // Everything ok + return *str1; +} + +// Position the cursor +void ssd1306_SetCursor(uint8_t x, uint8_t y) +{ + SSD1306.CurrentX = x; + SSD1306.CurrentY = y; +} + +// Draw line by Bresenhem's algorithm +void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) +{ + uint8_t x = x1; + uint8_t y = y1; + int32_t deltaX = abs(x2 - x1); + int32_t deltaY = abs(y2 - y1); + int32_t signX = ((x1 < x2) ? 1 : -1); + int32_t signY = ((y1 < y2) ? 1 : -1); + int32_t error = deltaX - deltaY; + int32_t error2; + ssd1306_DrawPixel(x2, y2, color); + while ((x1 != x2) || (y1 != y2)) { + ssd1306_DrawPixel(x1, y1, color); + error2 = error * DOUBLE; + if (error2 > -deltaY) { + error -= deltaY; + x += signX; + } else { + /* nothing to do */ + } + if (error2 < deltaX) { + error += deltaX; + y += signY; + } else { + /* nothing to do */ + } + } +} + +// Draw polyline +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color) +{ + uint16_t i; + if (par_vertex != 0) { + for (i = 1; i < par_size; i++) { + ssd1306_DrawLine(par_vertex[i - 1].x, par_vertex[i - 1].y, par_vertex[i].x, par_vertex[i].y, color); + } + } else { + /* nothing to do */ + } + return; +} + +// Draw circle by Bresenhem's algorithm +void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color) +{ + int32_t x = -par_r; + int32_t y = 0; + int32_t b = 2; + int32_t err = b - b * par_r; + int32_t e2; + + if (par_x >= SSD1306_WIDTH || par_y >= SSD1306_HEIGHT) { + return; + } + + do { + ssd1306_DrawPixel(par_x - x, par_y + y, par_color); + ssd1306_DrawPixel(par_x + x, par_y + y, par_color); + ssd1306_DrawPixel(par_x + x, par_y - y, par_color); + ssd1306_DrawPixel(par_x - x, par_y - y, par_color); + e2 = err; + if (e2 <= y) { + y++; + err = err + (y * b + 1); + if (-x == y && e2 <= x) { + e2 = 0; + } else { + /* nothing to do */ + } + } else { + /* nothing to do */ + } + if (e2 > x) { + x++; + err = err + (x * b + 1); + } else { + /* nothing to do */ + } + } while (x <= 0); + + return; +} + +// Draw rectangle +void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) +{ + ssd1306_DrawLine(x1, y1, x2, y1, color); + ssd1306_DrawLine(x2, y1, x2, y2, color); + ssd1306_DrawLine(x2, y2, x1, y2, color); + ssd1306_DrawLine(x1, y2, x1, y1, color); +} + +void ssd1306_DrawBitmap(const uint8_t *bitmap, uint32_t size) +{ + unsigned int c = 8; + uint8_t rows = size * c / SSD1306_WIDTH; + if (rows > SSD1306_HEIGHT) { + rows = SSD1306_HEIGHT; + } + for (uint8_t y = 0; y < rows; y++) { + for (uint8_t x = 0; x < SSD1306_WIDTH; x++) { + uint8_t byte = bitmap[(y * SSD1306_WIDTH / c) + (x / c)]; + uint8_t bit = byte & (0x80 >> (x % c)); + ssd1306_DrawPixel(x, y, bit ? White : Black); + } + } +} + +void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data, uint32_t size) +{ + uint32_t stride = w; + uint8_t h = w; // 字体宽高一样 + uint8_t width = w; + if (x + w > SSD1306_WIDTH || y + h > SSD1306_HEIGHT || w * h == 0) { + printf("%dx%d @ %d,%d out of range or invalid!\r\n", w, h, x, y); + return; + } + + width = (width <= SSD1306_WIDTH ? width : SSD1306_WIDTH); + h = (h <= SSD1306_HEIGHT ? h : SSD1306_HEIGHT); + stride = (stride == 0 ? w : stride); + unsigned int c = 8; + + uint8_t rows = size * c / stride; + for (uint8_t i = 0; i < rows; i++) { + uint32_t base = i * stride / c; + for (uint8_t j = 0; j < width; j++) { + uint32_t idx = base + (j / c); + uint8_t byte = idx < size ? data[idx] : 0; + uint8_t bit = byte & (0x80 >> (j % c)); + ssd1306_DrawPixel(x + j, y + i, bit ? White : Black); + } + } +} + +void ssd1306_SetContrast(const uint8_t value) +{ + const uint8_t kSetContrastControlRegister = 0x81; + ssd1306_WriteCommand(kSetContrastControlRegister); + ssd1306_WriteCommand(value); +} + +void ssd1306_SetDisplayOn(const uint8_t on) +{ + uint8_t value; + if (on) { + value = 0xAF; // Display on + SSD1306.DisplayOn = 1; + } else { + value = 0xAE; // Display off + SSD1306.DisplayOn = 0; + } + ssd1306_WriteCommand(value); +} + +uint8_t ssd1306_GetDisplayOn(void) +{ + return SSD1306.DisplayOn; +} + +int g_ssd1306_current_loc_v = 0; +#define SSD1306_INTERVAL_V (15) + +void ssd1306_ClearOLED(void) +{ + ssd1306_Fill(Black); + g_ssd1306_current_loc_v = 0; +} + +void ssd1306_printf(char *fmt, ...) +{ + char buffer[20]; + int ret = 0; + if (fmt) { + va_list argList; + va_start(argList, fmt); + ret = vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), fmt, argList); + if (ret < 0) { + printf("buffer is null\r\n"); + } + va_end(argList); + ssd1306_SetCursor(0, g_ssd1306_current_loc_v); + ssd1306_DrawString(buffer, Font_7x10, White); + + ssd1306_UpdateScreen(); + } + g_ssd1306_current_loc_v += SSD1306_INTERVAL_V; +} diff --git a/src/vendor/test/environment/ssd1306.h b/src/vendor/test/environment/ssd1306.h new file mode 100644 index 0000000000000000000000000000000000000000..769f19c7af3a3aaf0f6fd007d62721c007b0e7d1 --- /dev/null +++ b/src/vendor/test/environment/ssd1306.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 SSD1306_H +#define SSD1306_H + +#include +#include +#include "ssd1306_fonts.h" + +// SSD1306 OLED height in pixels +#ifndef SSD1306_HEIGHT +#define SSD1306_HEIGHT 64 +#endif + +// SSD1306 width in pixels +#ifndef SSD1306_WIDTH +#define SSD1306_WIDTH 128 +#endif + +// some LEDs don't display anything in first two columns + +#ifndef SSD1306_BUFFER_SIZE +#define SSD1306_BUFFER_SIZE (SSD1306_WIDTH * SSD1306_HEIGHT / 8) +#endif + +// Enumeration for screen colors +typedef enum { + Black = 0x00, // Black color, no pixel + White = 0x01 // Pixel is set. Color depends on OLED +} SSD1306_COLOR; + +typedef enum { + SSD1306_OK = 0x00, + SSD1306_ERR = 0x01 // Generic error. +} SSD1306_Error_t; + +// Struct to store transformations +typedef struct { + uint16_t CurrentX; + uint16_t CurrentY; + uint8_t Inverted; + uint8_t Initialized; + uint8_t DisplayOn; +} SSD1306_t; +typedef struct { + uint8_t x; + uint8_t y; +} SSD1306_VERTEX; + +// Procedure definitions +void ssd1306_Init(void); +void ssd1306_Fill(SSD1306_COLOR color); +void ssd1306_SetCursor(uint8_t x, uint8_t y); +void ssd1306_UpdateScreen(void); + +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color); +char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color); + +void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color); +void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color); +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color); +void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color); +void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color); +void ssd1306_DrawBitmap(const uint8_t *bitmap, uint32_t size); +void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data, uint32_t size); + +/** + * @brief Sets the contrast of the display. + * @param[in] value contrast to set. + * @note Contrast increases as the value increases. + * @note RESET = 7Fh. + */ +void ssd1306_SetContrast(const uint8_t value); +/** + * @brief Set Display ON/OFF. + * @param[in] on 0 for OFF, any for ON. + */ +void ssd1306_SetDisplayOn(const uint8_t on); +/** + * @brief Reads DisplayOn state. + * @return 0: OFF. + * 1: ON. + */ +uint8_t ssd1306_GetDisplayOn(void); + +// Low-level procedures +void ssd1306_Reset(void); +void ssd1306_WriteCommand(uint8_t byte); +void ssd1306_WriteData(uint8_t *buffer, size_t buff_size); +SSD1306_Error_t ssd1306_FillBuffer(uint8_t *buf, uint32_t len); +void ssd1306_ClearOLED(void); +void ssd1306_printf(char *fmt, ...); + +#endif // __SSD1306_H__ \ No newline at end of file diff --git a/src/vendor/test/environment/ssd1306_fonts.c b/src/vendor/test/environment/ssd1306_fonts.c new file mode 100644 index 0000000000000000000000000000000000000000..8053265cdef8a0474cc3506121ce65c54cc06d6f --- /dev/null +++ b/src/vendor/test/environment/ssd1306_fonts.c @@ -0,0 +1,819 @@ +/* + MIT License + + Copyright (c) 2018-2019, Alexey Dynda + + 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. +*/ +/* + * ssd1306xled_font6x8 is by Neven Boyanov + * ssd1306xled_font8x16 is by Neven Boyanov + * + * @created: 2014-08-12 + * @author: Neven Boyanov + * + * Copyright (c) 2015 Neven Boyanov, Tinusaur Team. All Rights Reserved. + * Distributed as open source software under MIT License, see LICENSE.txt file. + * Please, as a favour, retain the link http://tinusaur.org to The Tinusaur Project. + * + * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled + * + */ + +#include "ssd1306_fonts.h" + +/************************************6*8的点阵************************************/ +const unsigned char g_f6X8[][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // sp + {0x00, 0x00, 0x00, 0x2f, 0x00, 0x00}, // ! + {0x00, 0x00, 0x07, 0x00, 0x07, 0x00}, // " + {0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14}, // # + {0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12}, // $ + {0x00, 0x62, 0x64, 0x08, 0x13, 0x23}, // % + {0x00, 0x36, 0x49, 0x55, 0x22, 0x50}, // & + {0x00, 0x00, 0x05, 0x03, 0x00, 0x00}, // ' + {0x00, 0x00, 0x1c, 0x22, 0x41, 0x00}, // ( + {0x00, 0x00, 0x41, 0x22, 0x1c, 0x00}, // ) + {0x00, 0x14, 0x08, 0x3E, 0x08, 0x14}, // * + {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // + + {0x00, 0x00, 0x00, 0xA0, 0x60, 0x00}, // , + {0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // - + {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // . + {0x00, 0x20, 0x10, 0x08, 0x04, 0x02}, // / + {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0 + {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00}, // 1 + {0x00, 0x42, 0x61, 0x51, 0x49, 0x46}, // 2 + {0x00, 0x21, 0x41, 0x45, 0x4B, 0x31}, // 3 + {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10}, // 4 + {0x00, 0x27, 0x45, 0x45, 0x45, 0x39}, // 5 + {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6 + {0x00, 0x01, 0x71, 0x09, 0x05, 0x03}, // 7 + {0x00, 0x36, 0x49, 0x49, 0x49, 0x36}, // 8 + {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E}, // 9 + {0x00, 0x00, 0x36, 0x36, 0x00, 0x00}, // : + {0x00, 0x00, 0x56, 0x36, 0x00, 0x00}, // ;号 + {0x00, 0x08, 0x14, 0x22, 0x41, 0x00}, // < + {0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // = + {0x00, 0x00, 0x41, 0x22, 0x14, 0x08}, // > + {0x00, 0x02, 0x01, 0x51, 0x09, 0x06}, // ? + {0x00, 0x32, 0x49, 0x59, 0x51, 0x3E}, // @ + {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C}, // A + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36}, // B + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22}, // C + {0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C}, // D + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41}, // E + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01}, // F + {0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A}, // G + {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F}, // H + {0x00, 0x00, 0x41, 0x7F, 0x41, 0x00}, // I + {0x00, 0x20, 0x40, 0x41, 0x3F, 0x01}, // J + {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41}, // K + {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40}, // L + {0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F}, // M + {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F}, // N + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E}, // O + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x06}, // P + {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q + {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46}, // R + {0x00, 0x46, 0x49, 0x49, 0x49, 0x31}, // S + {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01}, // T + {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F}, // U + {0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F}, // V + {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F}, // W + {0x00, 0x63, 0x14, 0x08, 0x14, 0x63}, // X + {0x00, 0x07, 0x08, 0x70, 0x08, 0x07}, // Y + {0x00, 0x61, 0x51, 0x49, 0x45, 0x43}, // Z + {0x00, 0x00, 0x7F, 0x41, 0x41, 0x00}, // [ + {0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55}, // 55 + {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ] + {0x00, 0x04, 0x02, 0x01, 0x02, 0x04}, // ^ + {0x00, 0x40, 0x40, 0x40, 0x40, 0x40}, // _ + {0x00, 0x00, 0x01, 0x02, 0x04, 0x00}, // ' + {0x00, 0x20, 0x54, 0x54, 0x54, 0x78}, // a + {0x00, 0x7F, 0x48, 0x44, 0x44, 0x38}, // b + {0x00, 0x38, 0x44, 0x44, 0x44, 0x20}, // c + {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F}, // d + {0x00, 0x38, 0x54, 0x54, 0x54, 0x18}, // e + {0x00, 0x08, 0x7E, 0x09, 0x01, 0x02}, // f + {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C}, // g + {0x00, 0x7F, 0x08, 0x04, 0x04, 0x78}, // h + {0x00, 0x00, 0x44, 0x7D, 0x40, 0x00}, // i + {0x00, 0x40, 0x80, 0x84, 0x7D, 0x00}, // j + {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // k + {0x00, 0x00, 0x41, 0x7F, 0x40, 0x00}, // l + {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78}, // m + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x78}, // n + {0x00, 0x38, 0x44, 0x44, 0x44, 0x38}, // o + {0x00, 0xFC, 0x24, 0x24, 0x24, 0x18}, // p + {0x00, 0x18, 0x24, 0x24, 0x18, 0xFC}, // q + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x08}, // r + {0x00, 0x48, 0x54, 0x54, 0x54, 0x20}, // s + {0x00, 0x04, 0x3F, 0x44, 0x40, 0x20}, // t + {0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C}, // u + {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C}, // v + {0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C}, // w + {0x00, 0x44, 0x28, 0x10, 0x28, 0x44}, // x + {0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C}, // y + {0x00, 0x44, 0x64, 0x54, 0x4C, 0x44}, // z + {0x14, 0x14, 0x14, 0x14, 0x14, 0x14}, // horiz lines +}; + +/****************************************8*16的点阵************************************/ +const unsigned char g_f8X16[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, // ! 1 + 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " 2 + 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // # 3 + 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, // $ 4 + 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, // % 5 + 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, // & 6 + 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ' 7 + 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, // ( 8 + 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, // ) 9 + 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, // * 10 + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, // + 11 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // , 12 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // - 13 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // . 14 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, // / 15 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 16 + 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 17 + 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 18 + 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 19 + 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 20 + 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 21 + 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 22 + 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 23 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 24 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 25 + 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, // : 26 + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, // ;号 27 + 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, // < 28 + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, // = 29 + 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // > 30 + 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, // ? 31 + 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, // @ 32 + 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 33 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 34 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 35 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 36 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 37 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 38 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 39 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 40 + 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 41 + 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 42 + 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 43 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 44 + 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 45 + 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 46 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 47 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 48 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 49 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 50 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 51 + 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 52 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 53 + 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 54 + 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 55 + 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 56 + 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 57 + 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 58 + 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, // [ 59 + 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, // \ 60 + 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, // ] 61 + 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^ 62 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // _ 63 + 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ` 64 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 65 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 66 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 67 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 68 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 69 + 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 70 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 71 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 72 + 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 73 + 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 74 + 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 75 + 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 76 + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 77 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 78 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 79 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 80 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 81 + 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 82 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 83 + 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 84 + 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 85 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 86 + 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 87 + 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 88 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 89 + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 90 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, // { 91 + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // | 92 + 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, // } 93 + 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ~ 94 +}; + +static const unsigned short Font7x10[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ! + 0x2800, 0x2800, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x2400, 0x2400, 0x7C00, 0x2400, 0x4800, 0x7C00, 0x4800, 0x4800, 0x0000, 0x0000, // # + 0x3800, 0x5400, 0x5000, 0x3800, 0x1400, 0x5400, 0x5400, 0x3800, 0x1000, 0x0000, // $ + 0x2000, 0x5400, 0x5800, 0x3000, 0x2800, 0x5400, 0x1400, 0x0800, 0x0000, 0x0000, // % + 0x1000, 0x2800, 0x2800, 0x1000, 0x3400, 0x4800, 0x4800, 0x3400, 0x0000, 0x0000, // & + 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x0800, 0x1000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x1000, 0x0800, // ( + 0x2000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x1000, 0x2000, // ) + 0x1000, 0x3800, 0x1000, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * + 0x0000, 0x0000, 0x1000, 0x1000, 0x7C00, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // , + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3800, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // . + 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x0000, 0x0000, // / + 0x3800, 0x4400, 0x4400, 0x5400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 0 + 0x1000, 0x3000, 0x5000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // 1 + 0x3800, 0x4400, 0x4400, 0x0400, 0x0800, 0x1000, 0x2000, 0x7C00, 0x0000, 0x0000, // 2 + 0x3800, 0x4400, 0x0400, 0x1800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 3 + 0x0800, 0x1800, 0x2800, 0x2800, 0x4800, 0x7C00, 0x0800, 0x0800, 0x0000, 0x0000, // 4 + 0x7C00, 0x4000, 0x4000, 0x7800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 5 + 0x3800, 0x4400, 0x4000, 0x7800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 6 + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, // 7 + 0x3800, 0x4400, 0x4400, 0x3800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 8 + 0x3800, 0x4400, 0x4400, 0x4400, 0x3C00, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 9 + 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ; + 0x0000, 0x0000, 0x0C00, 0x3000, 0x4000, 0x3000, 0x0C00, 0x0000, 0x0000, 0x0000, // < + 0x0000, 0x0000, 0x0000, 0x7C00, 0x0000, 0x7C00, 0x0000, 0x0000, 0x0000, 0x0000, // = + 0x0000, 0x0000, 0x6000, 0x1800, 0x0400, 0x1800, 0x6000, 0x0000, 0x0000, 0x0000, // > + 0x3800, 0x4400, 0x0400, 0x0800, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ? + 0x3800, 0x4400, 0x4C00, 0x5400, 0x5C00, 0x4000, 0x4000, 0x3800, 0x0000, 0x0000, // @ + 0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000, // A + 0x7800, 0x4400, 0x4400, 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x0000, 0x0000, // B + 0x3800, 0x4400, 0x4000, 0x4000, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // C + 0x7000, 0x4800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4800, 0x7000, 0x0000, 0x0000, // D + 0x7C00, 0x4000, 0x4000, 0x7C00, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // E + 0x7C00, 0x4000, 0x4000, 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // F + 0x3800, 0x4400, 0x4000, 0x4000, 0x5C00, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // G + 0x4400, 0x4400, 0x4400, 0x7C00, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // H + 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3800, 0x0000, 0x0000, // I + 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // J + 0x4400, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // K + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // L + 0x4400, 0x6C00, 0x6C00, 0x5400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // M + 0x4400, 0x6400, 0x6400, 0x5400, 0x5400, 0x4C00, 0x4C00, 0x4400, 0x0000, 0x0000, // N + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // O + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // P + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x5400, 0x3800, 0x0400, 0x0000, // Q + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // R + 0x3800, 0x4400, 0x4000, 0x3000, 0x0800, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // S + 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // T + 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // U + 0x4400, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x1000, 0x0000, 0x0000, // V + 0x4400, 0x4400, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // W + 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, // X + 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // Y + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // Z + 0x1800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1800, // [ + 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0000, 0x0000, /* \ */ + 0x3000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3000, // ] + 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE00, // _ + 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x3800, 0x4400, 0x3C00, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // a + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x0000, 0x0000, // b + 0x0000, 0x0000, 0x3800, 0x4400, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // c + 0x0400, 0x0400, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // d + 0x0000, 0x0000, 0x3800, 0x4400, 0x7C00, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // e + 0x0C00, 0x1000, 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // f + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x7800, // g + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // h + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // i + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xE000, // j + 0x4000, 0x4000, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4400, 0x0000, 0x0000, // k + 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // l + 0x0000, 0x0000, 0x7800, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x0000, 0x0000, // m + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // n + 0x0000, 0x0000, 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // o + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x4000, 0x4000, // p + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x0400, // q + 0x0000, 0x0000, 0x5800, 0x6400, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // r + 0x0000, 0x0000, 0x3800, 0x4400, 0x3000, 0x0800, 0x4400, 0x3800, 0x0000, 0x0000, // s + 0x2000, 0x2000, 0x7800, 0x2000, 0x2000, 0x2000, 0x2000, 0x1800, 0x0000, 0x0000, // t + 0x0000, 0x0000, 0x4400, 0x4400, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // u + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x0000, 0x0000, // v + 0x0000, 0x0000, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // w + 0x0000, 0x0000, 0x4400, 0x2800, 0x1000, 0x1000, 0x2800, 0x4400, 0x0000, 0x0000, // x + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x6000, // y + 0x0000, 0x0000, 0x7C00, 0x0800, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // z + 0x1800, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1800, // { + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, // | + 0x3000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x3000, // } + 0x0000, 0x0000, 0x0000, 0x7400, 0x4C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +static const unsigned short Font11x18[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // ! + 0x0000, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x0000, 0x1980, 0x1980, 0x1980, 0x1980, 0x7FC0, 0x7FC0, 0x1980, 0x3300, + 0x7FC0, 0x7FC0, 0x3300, 0x3300, 0x3300, 0x3300, 0x0000, 0x0000, 0x0000, // # + 0x0000, 0x1E00, 0x3F00, 0x7580, 0x6580, 0x7400, 0x3C00, 0x1E00, 0x0700, + 0x0580, 0x6580, 0x6580, 0x7580, 0x3F00, 0x1E00, 0x0400, 0x0400, 0x0000, // $ + 0x0000, 0x7000, 0xD800, 0xD840, 0xD8C0, 0xD980, 0x7300, 0x0600, 0x0C00, + 0x1B80, 0x36C0, 0x66C0, 0x46C0, 0x06C0, 0x0380, 0x0000, 0x0000, 0x0000, // % + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x3300, 0x3300, 0x1E00, 0x0C00, 0x3CC0, + 0x66C0, 0x6380, 0x6180, 0x6380, 0x3EC0, 0x1C80, 0x0000, 0x0000, 0x0000, // & + 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x0080, 0x0100, 0x0300, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0300, 0x0100, 0x0080, // ( + 0x2000, 0x1000, 0x1800, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x1800, 0x1000, 0x2000, // ) + 0x0000, 0x0C00, 0x2D00, 0x3F00, 0x1E00, 0x3300, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * + 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0xFFC0, 0xFFC0, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800, // , + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // . + 0x0000, 0x0300, 0x0300, 0x0300, 0x0600, 0x0600, 0x0600, 0x0600, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000, // / + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6D80, 0x6D80, + 0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 0 + 0x0000, 0x0600, 0x0E00, 0x1E00, 0x3600, 0x2600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // 1 + 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, 0x6180, 0x0180, 0x0300, 0x0600, + 0x0C00, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // 2 + 0x0000, 0x1C00, 0x3E00, 0x6300, 0x6300, 0x0300, 0x0E00, 0x0E00, 0x0300, + 0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 3 + 0x0000, 0x0600, 0x0E00, 0x0E00, 0x1E00, 0x1E00, 0x1600, 0x3600, 0x3600, + 0x6600, 0x7F80, 0x7F80, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // 4 + 0x0000, 0x7F00, 0x7F00, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x6380, + 0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 5 + 0x0000, 0x1E00, 0x3F00, 0x3380, 0x6180, 0x6000, 0x6E00, 0x7F00, 0x7380, + 0x6180, 0x6180, 0x6180, 0x3380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 6 + 0x0000, 0x7F80, 0x7F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0600, 0x0C00, + 0x0C00, 0x0C00, 0x0800, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000, // 7 + 0x0000, 0x1E00, 0x3F00, 0x6380, 0x6180, 0x6180, 0x2100, 0x1E00, 0x3F00, + 0x6180, 0x6180, 0x6180, 0x6180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 8 + 0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, + 0x1D80, 0x0180, 0x6180, 0x7300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 9 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800, // ; + 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0380, 0x0E00, 0x3800, 0x6000, + 0x3800, 0x0E00, 0x0380, 0x0080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // < + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7F80, 0x7F80, 0x0000, 0x0000, + 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // = + 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x7000, 0x1C00, 0x0700, 0x0180, + 0x0700, 0x1C00, 0x7000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // > + 0x0000, 0x1F00, 0x3F80, 0x71C0, 0x60C0, 0x00C0, 0x01C0, 0x0380, 0x0700, + 0x0E00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // ? + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x7180, 0x6380, 0x6F80, 0x6D80, 0x6D80, + 0x6F80, 0x6780, 0x6000, 0x3200, 0x3E00, 0x1C00, 0x0000, 0x0000, 0x0000, // @ + 0x0000, 0x0E00, 0x0E00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x3180, 0x3180, + 0x3F80, 0x3F80, 0x3180, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000, // A + 0x0000, 0x7C00, 0x7E00, 0x6300, 0x6300, 0x6300, 0x6300, 0x7E00, 0x7E00, + 0x6300, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, 0x0000, 0x0000, 0x0000, // B + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6000, + 0x6000, 0x6000, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // C + 0x0000, 0x7C00, 0x7F00, 0x6300, 0x6380, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6300, 0x6300, 0x7E00, 0x7C00, 0x0000, 0x0000, 0x0000, // D + 0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, + 0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // E + 0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, + 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, // F + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6380, + 0x6380, 0x6180, 0x6180, 0x3180, 0x3F80, 0x1E00, 0x0000, 0x0000, 0x0000, // G + 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x7F80, 0x7F80, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // H + 0x0000, 0x3F00, 0x3F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3F00, 0x3F00, 0x0000, 0x0000, 0x0000, // I + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // J + 0x0000, 0x60C0, 0x6180, 0x6300, 0x6600, 0x6600, 0x6C00, 0x7800, 0x7C00, + 0x6600, 0x6600, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // K + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, + 0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // L + 0x0000, 0x71C0, 0x71C0, 0x7BC0, 0x7AC0, 0x6AC0, 0x6AC0, 0x6EC0, 0x64C0, + 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000, // M + 0x0000, 0x7180, 0x7180, 0x7980, 0x7980, 0x7980, 0x6D80, 0x6D80, 0x6D80, + 0x6580, 0x6780, 0x6780, 0x6780, 0x6380, 0x6380, 0x0000, 0x0000, 0x0000, // N + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // O + 0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6180, 0x6380, 0x7F00, + 0x7E00, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, // P + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6580, 0x6780, 0x3300, 0x3F80, 0x1E40, 0x0000, 0x0000, 0x0000, // Q + 0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, + 0x6600, 0x6300, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // R + 0x0000, 0x0E00, 0x1F00, 0x3180, 0x3180, 0x3000, 0x3800, 0x1E00, 0x0700, + 0x0380, 0x6180, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // S + 0x0000, 0xFFC0, 0xFFC0, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // T + 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // U + 0x0000, 0x60C0, 0x60C0, 0x60C0, 0x3180, 0x3180, 0x3180, 0x1B00, 0x1B00, + 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x0400, 0x0000, 0x0000, 0x0000, // V + 0x0000, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xCCC0, 0x4C80, 0x4C80, + 0x5E80, 0x5280, 0x5280, 0x7380, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // W + 0x0000, 0xC0C0, 0x6080, 0x6180, 0x3300, 0x3B00, 0x1E00, 0x0C00, 0x0C00, + 0x1E00, 0x1F00, 0x3B00, 0x7180, 0x6180, 0xC0C0, 0x0000, 0x0000, 0x0000, // X + 0x0000, 0xC0C0, 0x6180, 0x6180, 0x3300, 0x3300, 0x1E00, 0x1E00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // Y + 0x0000, 0x3F80, 0x3F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0C00, 0x0C00, + 0x1800, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // Z + 0x0F00, 0x0F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0F00, 0x0F00, // [ + 0x0000, 0x1800, 0x1800, 0x1800, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0300, 0x0300, 0x0300, 0x0000, 0x0000, 0x0000, /* \ */ + 0x1E00, 0x1E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x1E00, 0x1E00, // ] + 0x0000, 0x0C00, 0x0C00, 0x1E00, 0x1200, 0x3300, 0x3300, 0x6180, 0x6180, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFE0, 0x0000, // _ + 0x0000, 0x3800, 0x1800, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F00, 0x3F80, 0x6180, 0x0180, + 0x1F80, 0x3F80, 0x6180, 0x6380, 0x7F80, 0x38C0, 0x0000, 0x0000, 0x0000, // a + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x0000, 0x0000, 0x0000, // b + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, + 0x6000, 0x6000, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // c + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x1D80, 0x3F80, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0000, 0x0000, 0x0000, // d + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, + 0x7F80, 0x7F80, 0x6000, 0x7180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // e + 0x0000, 0x07C0, 0x0FC0, 0x0C00, 0x0C00, 0x7F80, 0x7F80, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // f + 0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x6380, 0x7F00, 0x3E00, // g + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6F00, 0x7F80, 0x7180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // h + 0x0000, 0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // i + 0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x4600, 0x7E00, 0x3C00, // j + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6180, 0x6300, 0x6600, 0x6C00, + 0x7C00, 0x7600, 0x6300, 0x6300, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // k + 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // l + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xFFC0, 0xCEC0, 0xCCC0, + 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0x0000, 0x0000, 0x0000, // m + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6F00, 0x7F80, 0x7180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // n + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // o + 0x0000, 0x0000, 0x0000, 0x0000, 0x6E00, 0x7F00, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x6000, 0x6000, 0x6000, 0x6000, // p + 0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x0180, 0x0180, 0x0180, // q + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6700, 0x3F80, 0x3900, 0x3000, + 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x0000, 0x0000, 0x0000, // r + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F80, 0x6180, 0x6000, + 0x7F00, 0x3F80, 0x0180, 0x6180, 0x7F00, 0x1E00, 0x0000, 0x0000, 0x0000, // s + 0x0000, 0x0000, 0x0800, 0x1800, 0x1800, 0x7F00, 0x7F00, 0x1800, 0x1800, + 0x1800, 0x1800, 0x1800, 0x1800, 0x1F80, 0x0F80, 0x0000, 0x0000, 0x0000, // t + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6380, 0x7F80, 0x3D80, 0x0000, 0x0000, 0x0000, // u + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x60C0, 0x3180, 0x3180, 0x3180, + 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0600, 0x0000, 0x0000, 0x0000, // v + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xDD80, 0xDD80, 0x5500, + 0x5500, 0x5500, 0x7700, 0x7700, 0x2200, 0x2200, 0x0000, 0x0000, 0x0000, // w + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x3300, 0x3300, 0x1E00, + 0x0C00, 0x0C00, 0x1E00, 0x3300, 0x3300, 0x6180, 0x0000, 0x0000, 0x0000, // x + 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x3180, 0x3300, 0x3300, + 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x1C00, 0x7C00, 0x7000, // y + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FC0, 0x7FC0, 0x0180, 0x0300, + 0x0600, 0x0C00, 0x1800, 0x3000, 0x7FC0, 0x7FC0, 0x0000, 0x0000, 0x0000, // z + 0x0380, 0x0780, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0E00, 0x1C00, + 0x1C00, 0x0E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0780, 0x0380, // { + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, // | + 0x3800, 0x3C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0E00, 0x0700, + 0x0700, 0x0E00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3C00, 0x3800, // } + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3880, 0x7F80, + 0x4700, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; +static const unsigned short Font16x26[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [ ] + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, + 0x01C0, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [!] + 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ["] + 0x01CE, 0x03CE, 0x03DE, 0x039E, 0x039C, 0x079C, 0x3FFF, 0x7FFF, 0x0738, 0x0F38, 0x0F78, 0x0F78, 0x0E78, 0xFFFF, + 0xFFFF, 0x1EF0, 0x1CF0, 0x1CE0, 0x3CE0, 0x3DE0, 0x39E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [#] + 0x03FC, 0x0FFE, 0x1FEE, 0x1EE0, 0x1EE0, 0x1EE0, 0x1EE0, 0x1FE0, 0x0FE0, 0x07E0, 0x03F0, 0x01FC, 0x01FE, 0x01FE, + 0x01FE, 0x01FE, 0x01FE, 0x01FE, 0x3DFE, 0x3FFC, 0x0FF0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, // Ascii = [$] + 0x3E03, 0xF707, 0xE78F, 0xE78E, 0xE39E, 0xE3BC, 0xE7B8, 0xE7F8, 0xF7F0, 0x3FE0, 0x01C0, 0x03FF, 0x07FF, 0x07F3, + 0x0FF3, 0x1EF3, 0x3CF3, 0x38F3, 0x78F3, 0xF07F, 0xE03F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [%] + 0x07E0, 0x0FF8, 0x0F78, 0x1F78, 0x1F78, 0x1F78, 0x0F78, 0x0FF0, 0x0FE0, 0x1F80, 0x7FC3, 0xFBC3, 0xF3E7, 0xF1F7, + 0xF0F7, 0xF0FF, 0xF07F, 0xF83E, 0x7C7F, 0x3FFF, 0x1FEF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [&] + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ['] + 0x003F, 0x007C, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x0780, 0x0780, 0x0F80, 0x0F00, 0x0F00, 0x0F00, 0x0F00, 0x0F00, + 0x0F00, 0x0F80, 0x0780, 0x0780, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x007C, 0x003F, 0x000F, 0x0000, // Ascii = [(] + 0x7E00, 0x1F00, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x00F0, 0x00F0, 0x00F8, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, + 0x0078, 0x00F8, 0x00F0, 0x00F0, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x1F00, 0x7E00, 0x7800, 0x0000, // Ascii = [)] + 0x03E0, 0x03C0, 0x01C0, 0x39CE, 0x3FFF, 0x3F7F, 0x0320, 0x0370, 0x07F8, 0x0F78, 0x1F3C, 0x0638, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [*] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0xFFFF, + 0xFFFF, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [+] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x0380, // Ascii = [,] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFE, 0x3FFE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [-] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [.] + 0x000F, 0x000F, 0x001E, 0x001E, 0x003C, 0x003C, 0x0078, 0x0078, 0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, + 0x0780, 0x0780, 0x0F00, 0x0F00, 0x1E00, 0x1E00, 0x3C00, 0x3C00, 0x7800, 0x7800, 0xF000, 0x0000, // Ascii = [/] + 0x07F0, 0x0FF8, 0x1F7C, 0x3E3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, + 0x7C1F, 0x7C1F, 0x3C1E, 0x3E3E, 0x1F7C, 0x0FF8, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [0] + 0x00F0, 0x07F0, 0x3FF0, 0x3FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, + 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [1] + 0x0FE0, 0x3FF8, 0x3C7C, 0x003C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x007C, 0x00F8, 0x01F0, 0x03E0, 0x07C0, + 0x0780, 0x0F00, 0x1E00, 0x3E00, 0x3C00, 0x3FFE, 0x3FFE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [2] + 0x0FF0, 0x1FF8, 0x1C7C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x00F8, 0x0FF0, 0x0FF8, 0x007C, 0x003E, 0x001E, + 0x001E, 0x001E, 0x001E, 0x003E, 0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [3] + 0x0078, 0x00F8, 0x00F8, 0x01F8, 0x03F8, 0x07F8, 0x07F8, 0x0F78, 0x1E78, 0x1E78, 0x3C78, 0x7878, 0x7878, 0xFFFF, + 0xFFFF, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [4] + 0x1FFC, 0x1FFC, 0x1FFC, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FE0, 0x1FF8, 0x00FC, 0x007C, 0x003E, 0x003E, + 0x001E, 0x003E, 0x003E, 0x003C, 0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [5] + 0x01FC, 0x07FE, 0x0F8E, 0x1F00, 0x1E00, 0x3E00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFC, 0x7F3E, 0x7E1F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3E0F, 0x1E1F, 0x1F3E, 0x0FFC, 0x03F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [6] + 0x3FFF, 0x3FFF, 0x3FFF, 0x000F, 0x001E, 0x001E, 0x003C, 0x0038, 0x0078, 0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, + 0x03C0, 0x0780, 0x0F80, 0x0F80, 0x0F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [7] + 0x07F8, 0x0FFC, 0x1F3E, 0x1E1E, 0x3E1E, 0x3E1E, 0x1E1E, 0x1F3C, 0x0FF8, 0x07F0, 0x0FF8, 0x1EFC, 0x3E3E, 0x3C1F, + 0x7C1F, 0x7C0F, 0x7C0F, 0x3C1F, 0x3F3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [8] + 0x07F0, 0x0FF8, 0x1E7C, 0x3C3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x3C1F, 0x3E3F, 0x1FFF, 0x07EF, 0x001F, + 0x001E, 0x001E, 0x003E, 0x003C, 0x38F8, 0x3FF0, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [9] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [:] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x0380, // Ascii = [;] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x000F, 0x003F, 0x00FC, 0x03F0, 0x0FC0, 0x3F00, 0xFE00, + 0x3F00, 0x0FC0, 0x03F0, 0x00FC, 0x003F, 0x000F, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [<] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [=] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE000, 0xF800, 0x7E00, 0x1F80, 0x07E0, 0x01F8, 0x007E, 0x001F, + 0x007E, 0x01F8, 0x07E0, 0x1F80, 0x7E00, 0xF800, 0xE000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [>] + 0x1FF0, 0x3FFC, 0x383E, 0x381F, 0x381F, 0x001E, 0x001E, 0x003C, 0x0078, 0x00F0, 0x01E0, 0x03C0, 0x03C0, 0x07C0, + 0x07C0, 0x0000, 0x0000, 0x0000, 0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [?] + 0x03F8, 0x0FFE, 0x1F1E, 0x3E0F, 0x3C7F, 0x78FF, 0x79EF, 0x73C7, 0xF3C7, 0xF38F, 0xF38F, 0xF38F, 0xF39F, 0xF39F, + 0x73FF, 0x7BFF, 0x79F7, 0x3C00, 0x1F1C, 0x0FFC, 0x03F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [@] + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x07F0, 0x0F78, 0x0F78, 0x0E7C, 0x1E3C, 0x1E3C, 0x3C3E, + 0x3FFE, 0x3FFF, 0x781F, 0x780F, 0xF00F, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [A] + 0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FFC, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7C, 0x3FF0, 0x3FF8, 0x3C7E, + 0x3C1F, 0x3C1F, 0x3C0F, 0x3C0F, 0x3C1F, 0x3FFE, 0x3FF8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [B] + 0x0000, 0x0000, 0x0000, 0x01FF, 0x07FF, 0x1F87, 0x3E00, 0x3C00, 0x7C00, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, + 0x7C00, 0x7C00, 0x3E00, 0x3F00, 0x1F83, 0x07FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [C] + 0x0000, 0x0000, 0x0000, 0x7FF0, 0x7FFC, 0x787E, 0x781F, 0x781F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, + 0x780F, 0x780F, 0x781F, 0x781E, 0x787E, 0x7FF8, 0x7FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [D] + 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFE, 0x3FFE, 0x3E00, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [E] + 0x0000, 0x0000, 0x0000, 0x1FFF, 0x1FFF, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FFF, 0x1FFF, 0x1E00, + 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [F] + 0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x7C00, 0x7C00, 0x7800, 0xF800, 0xF800, 0xF87F, 0xF87F, + 0x780F, 0x7C0F, 0x7C0F, 0x3E0F, 0x1F8F, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [G] + 0x0000, 0x0000, 0x0000, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7FFF, 0x7FFF, 0x7C1F, + 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [H] + 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [I] + 0x0000, 0x0000, 0x0000, 0x1FFC, 0x1FFC, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, + 0x007C, 0x007C, 0x0078, 0x0078, 0x38F8, 0x3FF0, 0x3FC0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [J] + 0x0000, 0x0000, 0x0000, 0x3C1F, 0x3C1E, 0x3C3C, 0x3C78, 0x3CF0, 0x3DE0, 0x3FE0, 0x3FC0, 0x3F80, 0x3FC0, 0x3FE0, + 0x3DF0, 0x3CF0, 0x3C78, 0x3C7C, 0x3C3E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [K] + 0x0000, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [L] + 0x0000, 0x0000, 0x0000, 0xF81F, 0xFC1F, 0xFC1F, 0xFE3F, 0xFE3F, 0xFE3F, 0xFF7F, 0xFF77, 0xFF77, 0xF7F7, 0xF7E7, + 0xF3E7, 0xF3E7, 0xF3C7, 0xF007, 0xF007, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [M] + 0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7E0F, 0x7F0F, 0x7F0F, 0x7F8F, 0x7F8F, 0x7FCF, 0x7BEF, 0x79EF, 0x79FF, + 0x78FF, 0x78FF, 0x787F, 0x783F, 0x783F, 0x781F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [N] + 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, + 0xF80F, 0x780F, 0x780F, 0x7C1F, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [O] + 0x0000, 0x0000, 0x0000, 0x3FFC, 0x3FFF, 0x3E1F, 0x3E0F, 0x3E0F, 0x3E0F, 0x3E0F, 0x3E1F, 0x3E3F, 0x3FFC, 0x3FF0, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [P] + 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, + 0xF80F, 0x780F, 0x780F, 0x7C1F, 0x3E3E, 0x1FFC, 0x07F8, 0x007C, 0x003F, 0x000F, 0x0003, 0x0000, // Ascii = [Q] + 0x0000, 0x0000, 0x0000, 0x3FF0, 0x3FFC, 0x3C7E, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C3C, 0x3CFC, 0x3FF0, 0x3FE0, + 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, 0x3C1E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [R] + 0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x3E0E, 0x3C00, 0x3C00, 0x3C00, 0x3E00, 0x1FC0, 0x0FF8, 0x03FE, 0x007F, + 0x001F, 0x000F, 0x000F, 0x201F, 0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [S] + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [T] + 0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, + 0x7C0F, 0x7C0F, 0x3C1E, 0x3C1E, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [U] + 0x0000, 0x0000, 0x0000, 0xF007, 0xF007, 0xF807, 0x780F, 0x7C0F, 0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1F3C, 0x1F78, + 0x0F78, 0x0FF8, 0x07F0, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [V] + 0x0000, 0x0000, 0x0000, 0xE003, 0xF003, 0xF003, 0xF007, 0xF3E7, 0xF3E7, 0xF3E7, 0x73E7, 0x7BF7, 0x7FF7, 0x7FFF, + 0x7F7F, 0x7F7F, 0x7F7E, 0x3F7E, 0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [W] + 0x0000, 0x0000, 0x0000, 0xF807, 0x7C0F, 0x3E1E, 0x3E3E, 0x1F3C, 0x0FF8, 0x07F0, 0x07E0, 0x03E0, 0x03E0, 0x07F0, + 0x0FF8, 0x0F7C, 0x1E7C, 0x3C3E, 0x781F, 0x780F, 0xF00F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [X] + 0x0000, 0x0000, 0x0000, 0xF807, 0x7807, 0x7C0F, 0x3C1E, 0x3E1E, 0x1F3C, 0x0F78, 0x0FF8, 0x07F0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Y] + 0x0000, 0x0000, 0x0000, 0x7FFF, 0x7FFF, 0x000F, 0x001F, 0x003E, 0x007C, 0x00F8, 0x00F0, 0x01E0, 0x03E0, 0x07C0, + 0x0F80, 0x0F00, 0x1E00, 0x3E00, 0x7C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Z] + 0x07FF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, + 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x07FF, 0x07FF, 0x0000, // Ascii = [[] + 0x7800, 0x7800, 0x3C00, 0x3C00, 0x1E00, 0x1E00, 0x0F00, 0x0F00, 0x0780, 0x0780, 0x03C0, 0x03C0, 0x01E0, 0x01E0, + 0x00F0, 0x00F0, 0x0078, 0x0078, 0x003C, 0x003C, 0x001E, 0x001E, 0x000F, 0x000F, 0x0007, 0x0000, // Ascii = [\] + 0x7FF0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, + 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x7FF0, 0x7FF0, 0x0000, // Ascii = []] + 0x00C0, 0x01C0, 0x01C0, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x0778, 0x0F78, 0x0F38, 0x1E3C, 0x1E3C, 0x3C1E, 0x3C1E, + 0x380F, 0x780F, 0x7807, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [^] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, // Ascii = [_] + 0x00F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [`] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0FF8, 0x3FFC, 0x3C7C, 0x003E, 0x003E, 0x003E, 0x07FE, 0x1FFE, + 0x3E3E, 0x7C3E, 0x783E, 0x7C3E, 0x7C7E, 0x3FFF, 0x1FCF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [a] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFE, 0x3F3E, 0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3C1F, 0x3C1E, 0x3F3E, 0x3FFC, 0x3BF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [b] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x3E00, 0x3C00, 0x7C00, 0x7C00, + 0x7C00, 0x3C00, 0x3E00, 0x3E00, 0x1F87, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [c] + 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x07FF, 0x1FFF, 0x3E3F, 0x3C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x781F, + 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, 0x3E7F, 0x1FFF, 0x0FDF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [d] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03F8, 0x0FFC, 0x1F3E, 0x3E1E, 0x3C1F, 0x7C1F, 0x7FFF, 0x7FFF, + 0x7C00, 0x7C00, 0x3C00, 0x3E00, 0x1F07, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [e] + 0x01FF, 0x03E1, 0x03C0, 0x07C0, 0x07C0, 0x07C0, 0x7FFF, 0x7FFF, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, + 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [f] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EF, 0x1FFF, 0x3E7F, 0x3C1F, 0x7C1F, 0x7C1F, 0x781F, 0x781F, + 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, 0x3E7F, 0x1FFF, 0x0FDF, 0x001E, 0x001E, 0x001E, 0x387C, 0x3FF8, // Ascii = [g] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DFC, 0x3FFE, 0x3F9E, 0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, + 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [h] + 0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FE0, 0x7FE0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, + 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [i] + 0x00F8, 0x00F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FF8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, + 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F0, 0x71F0, 0x7FE0, // Ascii = [j] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C1F, 0x3C3E, 0x3C7C, 0x3CF8, 0x3DF0, 0x3DE0, 0x3FC0, 0x3FC0, + 0x3FE0, 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [k] + 0x7FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, + 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [l] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF79E, 0xFFFF, 0xFFFF, 0xFFFF, 0xFBE7, 0xF9E7, 0xF1C7, 0xF1C7, + 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [m] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DFC, 0x3FFE, 0x3F9E, 0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, + 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [n] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x3C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, + 0x780F, 0x780F, 0x7C1F, 0x3C1F, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [o] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DF8, 0x3FFE, 0x3F3E, 0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3C1F, 0x3E1E, 0x3F3E, 0x3FFC, 0x3FF8, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, // Ascii = [p] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EE, 0x1FFE, 0x3E7E, 0x3C1E, 0x7C1E, 0x781E, 0x781E, 0x781E, + 0x781E, 0x781E, 0x7C1E, 0x7C3E, 0x3E7E, 0x1FFE, 0x0FDE, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, // Ascii = [q] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F7F, 0x1FFF, 0x1FE7, 0x1FC7, 0x1F87, 0x1F00, 0x1F00, 0x1F00, + 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [r] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x1E0E, 0x3E00, 0x3E00, 0x3F00, 0x1FE0, 0x07FC, + 0x00FE, 0x003E, 0x001E, 0x001E, 0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [s] + 0x0000, 0x0000, 0x0000, 0x0780, 0x0780, 0x0780, 0x7FFF, 0x7FFF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, + 0x0780, 0x0780, 0x0780, 0x0780, 0x07C0, 0x03FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [t] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, + 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7E, 0x3EFE, 0x1FFE, 0x0FDE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [u] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF007, 0x780F, 0x780F, 0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1E3C, + 0x0F78, 0x0F78, 0x0FF0, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [v] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF003, 0xF1E3, 0xF3E3, 0xF3E7, 0xF3F7, 0xF3F7, 0x7FF7, 0x7F77, + 0x7F7F, 0x7F7F, 0x7F7F, 0x3E3E, 0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [w] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7C0F, 0x3E1E, 0x3E3C, 0x1F3C, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, + 0x07F0, 0x07F8, 0x0FF8, 0x1E7C, 0x3E3E, 0x3C1F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [x] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF807, 0x780F, 0x7C0F, 0x3C1E, 0x3C1E, 0x1E3C, 0x1E3C, 0x1F3C, + 0x0F78, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x0780, 0x0F80, 0x7F00, // Ascii = [y] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x001F, 0x003E, 0x007C, 0x00F8, 0x01F0, 0x03E0, + 0x07C0, 0x0F80, 0x1F00, 0x1E00, 0x3C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [z] + 0x01FE, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x3F80, 0x3F80, 0x03C0, + 0x01C0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x03E0, 0x01FE, 0x007E, 0x0000, // Ascii = [{] + 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, + 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, // Ascii = [|] + 0x3FC0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x03C0, 0x01C0, 0x01E0, 0x00FE, 0x00FE, 0x01E0, + 0x01C0, 0x03C0, 0x03C0, 0x01C0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x03E0, 0x3FC0, 0x3F00, 0x0000, // Ascii = [}] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3F07, 0x7FC7, 0x73E7, + 0xF1FF, 0xF07E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [~] +}; +static const unsigned short Font6x8[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, 0x2000, 0x0000, // ! + 0x5000, 0x5000, 0x5000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x5000, 0x5000, 0xf800, 0x5000, 0xf800, 0x5000, 0x5000, 0x0000, // # + 0x2000, 0x7800, 0xa000, 0x7000, 0x2800, 0xf000, 0x2000, 0x0000, // $ + 0xc000, 0xc800, 0x1000, 0x2000, 0x4000, 0x9800, 0x1800, 0x0000, // % + 0x4000, 0xa000, 0xa000, 0x4000, 0xa800, 0x9000, 0x6800, 0x0000, // & + 0x3000, 0x3000, 0x2000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x1000, 0x2000, 0x4000, 0x4000, 0x4000, 0x2000, 0x1000, 0x0000, // ( + 0x4000, 0x2000, 0x1000, 0x1000, 0x1000, 0x2000, 0x4000, 0x0000, // ) + 0x2000, 0xa800, 0x7000, 0xf800, 0x7000, 0xa800, 0x2000, 0x0000, // * + 0x0000, 0x2000, 0x2000, 0xf800, 0x2000, 0x2000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3000, 0x2000, 0x0000, // , + 0x0000, 0x0000, 0x0000, 0xf800, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3000, 0x0000, // . + 0x0000, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x0000, 0x0000, // / + 0x7000, 0x8800, 0x9800, 0xa800, 0xc800, 0x8800, 0x7000, 0x0000, // 0 + 0x2000, 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // 1 + 0x7000, 0x8800, 0x0800, 0x7000, 0x8000, 0x8000, 0xf800, 0x0000, // 2 + 0xf800, 0x0800, 0x1000, 0x3000, 0x0800, 0x8800, 0x7000, 0x0000, // 3 + 0x1000, 0x3000, 0x5000, 0x9000, 0xf800, 0x1000, 0x1000, 0x0000, // 4 + 0xf800, 0x8000, 0xf000, 0x0800, 0x0800, 0x8800, 0x7000, 0x0000, // 5 + 0x3800, 0x4000, 0x8000, 0xf000, 0x8800, 0x8800, 0x7000, 0x0000, // 6 + 0xf800, 0x0800, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x0000, // 7 + 0x7000, 0x8800, 0x8800, 0x7000, 0x8800, 0x8800, 0x7000, 0x0000, // 8 + 0x7000, 0x8800, 0x8800, 0x7800, 0x0800, 0x1000, 0xe000, 0x0000, // 9 + 0x0000, 0x0000, 0x2000, 0x0000, 0x2000, 0x0000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x2000, 0x0000, 0x2000, 0x2000, 0x4000, 0x0000, // ; + 0x0800, 0x1000, 0x2000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0000, // < + 0x0000, 0x0000, 0xf800, 0x0000, 0xf800, 0x0000, 0x0000, 0x0000, // = + 0x4000, 0x2000, 0x1000, 0x0800, 0x1000, 0x2000, 0x4000, 0x0000, // > + 0x7000, 0x8800, 0x0800, 0x3000, 0x2000, 0x0000, 0x2000, 0x0000, // ? + 0x7000, 0x8800, 0xa800, 0xb800, 0xb000, 0x8000, 0x7800, 0x0000, // @ + 0x2000, 0x5000, 0x8800, 0x8800, 0xf800, 0x8800, 0x8800, 0x0000, // A + 0xf000, 0x8800, 0x8800, 0xf000, 0x8800, 0x8800, 0xf000, 0x0000, // B + 0x7000, 0x8800, 0x8000, 0x8000, 0x8000, 0x8800, 0x7000, 0x0000, // C + 0xf000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0xf000, 0x0000, // D + 0xf800, 0x8000, 0x8000, 0xf000, 0x8000, 0x8000, 0xf800, 0x0000, // E + 0xf800, 0x8000, 0x8000, 0xf000, 0x8000, 0x8000, 0x8000, 0x0000, // F + 0x7800, 0x8800, 0x8000, 0x8000, 0x9800, 0x8800, 0x7800, 0x0000, // G + 0x8800, 0x8800, 0x8800, 0xf800, 0x8800, 0x8800, 0x8800, 0x0000, // H + 0x7000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // I + 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x9000, 0x6000, 0x0000, // J + 0x8800, 0x9000, 0xa000, 0xc000, 0xa000, 0x9000, 0x8800, 0x0000, // K + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0xf800, 0x0000, // L + 0x8800, 0xd800, 0xa800, 0xa800, 0xa800, 0x8800, 0x8800, 0x0000, // M + 0x8800, 0x8800, 0xc800, 0xa800, 0x9800, 0x8800, 0x8800, 0x0000, // N + 0x7000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // O + 0xf000, 0x8800, 0x8800, 0xf000, 0x8000, 0x8000, 0x8000, 0x0000, // P + 0x7000, 0x8800, 0x8800, 0x8800, 0xa800, 0x9000, 0x6800, 0x0000, // Q + 0xf000, 0x8800, 0x8800, 0xf000, 0xa000, 0x9000, 0x8800, 0x0000, // R + 0x7000, 0x8800, 0x8000, 0x7000, 0x0800, 0x8800, 0x7000, 0x0000, // S + 0xf800, 0xa800, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, // T + 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // U + 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x5000, 0x2000, 0x0000, // V + 0x8800, 0x8800, 0x8800, 0xa800, 0xa800, 0xa800, 0x5000, 0x0000, // W + 0x8800, 0x8800, 0x5000, 0x2000, 0x5000, 0x8800, 0x8800, 0x0000, // X + 0x8800, 0x8800, 0x5000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, // Y + 0xf800, 0x0800, 0x1000, 0x7000, 0x4000, 0x8000, 0xf800, 0x0000, // Z + 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7800, 0x0000, // [ + 0x0000, 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0000, 0x0000, /* \ */ + 0x7800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x7800, 0x0000, // ] + 0x2000, 0x5000, 0x8800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf800, 0x0000, // _ + 0x6000, 0x6000, 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x6000, 0x1000, 0x7000, 0x9000, 0x7800, 0x0000, // a + 0x8000, 0x8000, 0xb000, 0xc800, 0x8800, 0xc800, 0xb000, 0x0000, // b + 0x0000, 0x0000, 0x7000, 0x8800, 0x8000, 0x8800, 0x7000, 0x0000, // c + 0x0800, 0x0800, 0x6800, 0x9800, 0x8800, 0x9800, 0x6800, 0x0000, // d + 0x0000, 0x0000, 0x7000, 0x8800, 0xf800, 0x8000, 0x7000, 0x0000, // e + 0x1000, 0x2800, 0x2000, 0x7000, 0x2000, 0x2000, 0x2000, 0x0000, // f + 0x0000, 0x0000, 0x7000, 0x9800, 0x9800, 0x6800, 0x0800, 0x0000, // g + 0x8000, 0x8000, 0xb000, 0xc800, 0x8800, 0x8800, 0x8800, 0x0000, // h + 0x2000, 0x0000, 0x6000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // i + 0x1000, 0x0000, 0x1000, 0x1000, 0x1000, 0x9000, 0x6000, 0x0000, // j + 0x8000, 0x8000, 0x9000, 0xa000, 0xc000, 0xa000, 0x9000, 0x0000, // k + 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // l + 0x0000, 0x0000, 0xd000, 0xa800, 0xa800, 0xa800, 0xa800, 0x0000, // m + 0x0000, 0x0000, 0xb000, 0xc800, 0x8800, 0x8800, 0x8800, 0x0000, // n + 0x0000, 0x0000, 0x7000, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // o + 0x0000, 0x0000, 0xb000, 0xc800, 0xc800, 0xb000, 0x8000, 0x0000, // p + 0x0000, 0x0000, 0x6800, 0x9800, 0x9800, 0x6800, 0x0800, 0x0000, // q + 0x0000, 0x0000, 0xb000, 0xc800, 0x8000, 0x8000, 0x8000, 0x0000, // r + 0x0000, 0x0000, 0x7800, 0x8000, 0x7000, 0x0800, 0xf000, 0x0000, // s + 0x2000, 0x2000, 0xf800, 0x2000, 0x2000, 0x2800, 0x1000, 0x0000, // t + 0x0000, 0x0000, 0x8800, 0x8800, 0x8800, 0x9800, 0x6800, 0x0000, // u + 0x0000, 0x0000, 0x8800, 0x8800, 0x8800, 0x5000, 0x2000, 0x0000, // v + 0x0000, 0x0000, 0x8800, 0x8800, 0xa800, 0xa800, 0x5000, 0x0000, // w + 0x0000, 0x0000, 0x8800, 0x5000, 0x2000, 0x5000, 0x8800, 0x0000, // x + 0x0000, 0x0000, 0x8800, 0x8800, 0x7800, 0x0800, 0x8800, 0x0000, // y + 0x0000, 0x0000, 0xf800, 0x1000, 0x2000, 0x4000, 0xf800, 0x0000, // z + 0x1000, 0x2000, 0x2000, 0x4000, 0x2000, 0x2000, 0x1000, 0x0000, // { + 0x2000, 0x2000, 0x2000, 0x0000, 0x2000, 0x2000, 0x2000, 0x0000, // | + 0x4000, 0x2000, 0x2000, 0x1000, 0x2000, 0x2000, 0x4000, 0x0000, // } + 0x4000, 0xa800, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +FontDef Font_7x10 = {7, 10, Font7x10}; +FontDef Font_6x8 = {6, 8, Font6x8}; +FontDef Font_11x18 = {11, 18, Font11x18}; +FontDef Font_16x26 = {16, 26, Font16x26}; \ No newline at end of file diff --git a/src/vendor/test/environment/ssd1306_fonts.h b/src/vendor/test/environment/ssd1306_fonts.h new file mode 100644 index 0000000000000000000000000000000000000000..21afb48aa124f6e4579b1520082c9d3571f381db --- /dev/null +++ b/src/vendor/test/environment/ssd1306_fonts.h @@ -0,0 +1,58 @@ +/* + MIT License + + Copyright (c) 2018, Alexey Dynda + + 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. +*/ +/** + * @file ssd1306_fonts.h Fonts for monochrome/rgb oled display + */ + +#ifndef SSD1306_FONTS_H +#define SSD1306_FONTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup LCD_FONTS FONTS: Supported LCD fonts + * @{ + */ + +extern const unsigned char g_f6X8[][6]; +extern const unsigned char g_f8X16[]; + +typedef struct { + const unsigned char FontWidth; /*!< Font width in pixels */ + unsigned char FontHeight; /*!< Font height in pixels */ + const unsigned short *data; /*!< Pointer to data font data array */ +} FontDef; + +extern FontDef Font_7x10; +extern FontDef Font_6x8; +extern FontDef Font_11x18; +extern FontDef Font_16x26; + +#ifdef __cplusplus +} +#endif + +#endif // SSD1306_FONTS_H \ No newline at end of file diff --git a/src/vendor/test/event/CMakeLists.txt b/src/vendor/test/event/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3825d390b97916df8a09e59868a6c89880f18c67 --- /dev/null +++ b/src/vendor/test/event/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/event_example.c" PARENT_SCOPE) diff --git a/src/vendor/test/event/README.md b/src/vendor/test/event/README.md new file mode 100644 index 0000000000000000000000000000000000000000..926e609a72b6c923b4d6cfb44183e38b1d599892 --- /dev/null +++ b/src/vendor/test/event/README.md @@ -0,0 +1,116 @@ +## 任务 + +## 1.1 介绍 + +**功能介绍:** 本实验内容实现了任务间的同步,多任务环境下,任务之间往往需要同步操作,一个等待即是一个同步,事件可以提供一对多、多对多的同步操作。 + +**软件概述:** 写事件时,对指定事件写入指定的事件类型,可以一次同时写多个事件类型。读事件可以选取读取模式,所有事件,读取掩码中所有事件类型,只有读取的所有事件类型都发生,才能读取成功;任一事件,读取掩码中任一事件类型,读取的事件中任一一种类型发生,即可读取成功。 + +**硬件概述:** 核心板。硬件搭建要求如图所示: + + image-20240226173007100 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V00、HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.T3及以上 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + ![image-20240227100118269](../../../docs/pic/event/image-20240227100118269.png) + +## 1.4 接口介绍 + +### 1.4.1 osal_event_init() + +| **定义:** | int osal_event_init(osal_event *event_obj); | +| ------------ | ------------------------------------------- | +| **功能:** | 初始化一个事件控制模块 | +| **参数:** | event_obj:事件 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\event\osal_event.h | + +### 1.4.2 osal_event_read() + +| 定义: | int osal_event_read(osal_event *event_obj, unsigned int mask, unsigned int timeout_ms, unsigned int mode); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 阻塞读取指定事件类型,等待超时时间为相对时间,单位:ms | +| **参数:** | event_obj:事件
mask:事件掩码
timeout_ms:超时时间
mode:事件类型 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\event\osal_event.h | + +### 1.4.3 osal_event_write() + +| **定义:** | int osal_event_write(osal_event *event_obj, unsigned int mask); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 写指定的事件类型 | +| **参数:** | event_obj:事件
mask:事件掩码 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\event\osal_event.h | + +### 1.4.4 osal_event_clear() + +| **定义:** | int osal_event_clear(osal_event *event_obj, unsigned int mask); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 清除指定的事件类型 | +| **参数:** | event_obj:事件
mask:事件掩码 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\event\osal_event.h | + +### 1.4.5 osal_event_destroy() + +| **定义:** | errcode_t uapi_timer_deinit(void); | +| ------------ | ----------------------------------------- | +| **功能:** | 销毁指定的事件控制块 | +| **参数:** | void类型 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\event\osal_event.h | + +## 1.5 具体实现 + + 步骤一:调用事件初始化osal_event_init接口,初始化事件等待队列。 + + 步骤二:写事件osal_event_write,配置事件掩码类型。 + + 步骤三:读事件osal_event_read,选择读取模式。 + + 步骤四:清除事件osal_event_clear,清除指定事件类型 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”event“。 + + ![image-20240205104416249](../../../docs/pic/event/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\event文件里面内容拷贝到**步骤一创建的Sample文件夹中”event“**。 + + ![image-20240401150957191](../../../docs/pic/event/image-20240401150957191.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support EVENT Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240401150805884 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/event/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/event/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/event/image-20240205110327591-171194017584310.png) + +- 步骤七:软件烧录成功后,按一下开发板的RESET按键复位开发板,烧录完成后,串口打印信息如下。 + + ![image-20240227100118269](../../../docs/pic/event/image-20240227100118269.png) \ No newline at end of file diff --git a/src/vendor/test/event/event_example.c b/src/vendor/test/event/event_example.c new file mode 100644 index 0000000000000000000000000000000000000000..05d39265c7fb564f33f6780972e2f0911f610212 --- /dev/null +++ b/src/vendor/test/event/event_example.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., LIMITED. + * 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 "pinctrl.h" +#include "common_def.h" +#include "soc_osal.h" +#include "osal_wait.h" +#include "app_init.h" + +#define TEST_EVENT (1 << 0) // 事件掩码类型 +#define READ_TASK_PRI_EVENT 24 +#define WRITE_TASK_PRI_EVENT 25 +#define EVENT_TASK_STACK_SIZE 0x1000 +#define EVENT_TASK_PRIO 17 +#define TASK_STACK_SIZE 0xc00 + +static osal_event g_event_id; +uint32_t status = 0; + +static void example_event_read(const char *arg) +{ + unused(arg); + uint32_t ret; + // 超时等待读事件,超时时间为永远等待 + printf("example_event wait event 0x%x\r\n", TEST_EVENT); + ret = osal_event_read(&g_event_id, TEST_EVENT, OSAL_WAIT_FOREVER, OSAL_WAITMODE_AND); + if (ret == 1) { + printf("example_event read event 0x%x\r\n", TEST_EVENT); + } else { + printf("example_event read event failed\r\n"); + } +} + +static void example_event_write(const char *arg) +{ + unused(arg); + uint32_t ret = 0; + // 写用例任务等待事件 + printf("example_task_entry_event write event\r\n"); + ret = osal_event_write(&g_event_id, TEST_EVENT); + if (ret != OSAL_SUCCESS) { + printf("event write failed\r\n"); + } + printf("example_task_entry_event event write success\r\n"); + // 清除标志位 + ret = osal_event_clear(&g_event_id, TEST_EVENT); + if (ret != OSAL_SUCCESS) { + printf("event clear failed\r\n"); + } + printf("example_task_event event clear success\r\n"); +} + +void event_task_entry(void) +{ + uint32_t ret = 0; + osal_task *example_task1_info, *example_task2_info; + // 初始化事件 + osal_event_init(&g_event_id); + // 创建任务期间锁住任务调度 + osal_kthread_lock(); + // 创建任务1 + example_task1_info = osal_kthread_create((osal_kthread_handler)example_event_read, NULL, "example_task1", + TASK_STACK_SIZE); + ret = osal_kthread_set_priority(example_task1_info, READ_TASK_PRI_EVENT); + if (ret != OSAL_SUCCESS) { + printf("example_task1 creat failed\r\n"); + } + example_task2_info = osal_kthread_create((osal_kthread_handler)example_event_write, NULL, "example_task2", + TASK_STACK_SIZE); + ret = osal_kthread_set_priority(example_task2_info, WRITE_TASK_PRI_EVENT); + if (ret != OSAL_SUCCESS) { + printf("example_task2 creat failed\r\n"); + } + osal_kthread_unlock(); +} + +/* Run the EventTask_entry. */ +app_run(event_task_entry); \ No newline at end of file diff --git a/src/vendor/test/gyro/CMakeLists.txt b/src/vendor/test/gyro/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f0618260906ff9abb0267a82659fd32e326e57df --- /dev/null +++ b/src/vendor/test/gyro/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/spi_master_gyro.c" "${CMAKE_CURRENT_SOURCE_DIR}/ssd1306_fonts.c" "${CMAKE_CURRENT_SOURCE_DIR}/ssd1306.c" PARENT_SCOPE) \ No newline at end of file diff --git a/src/vendor/test/gyro/README.md b/src/vendor/test/gyro/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4707ff6f484c8daf478936a5cf80739f3708f6ee --- /dev/null +++ b/src/vendor/test/gyro/README.md @@ -0,0 +1,145 @@ +# gyro + +## 1.1 介绍 + +**功能介绍:** 通过陀螺仪模块在SSD1306 OLED屏幕显示当前偏航角、俯仰角、横滚角。 + +**软件概述:** SPI是一种同步数据通信总线,它支持全双工操作,可配置为3种工作模式:单主单从、单主多从、多主多从。SPI至少需要4根线,分别是主机输入从机输出MISO、时钟SCLK、片选CS,但如果只连接一个从机,则可以省略CS信号。 + +**硬件概述:** 核心板、OLED板,OLED数据手册参考:https://gitee.com/HiSpark/hi3861_hdu_iot_application/issues/I6WPSS?from=project-issue 里面的液晶显示器.pdf。 通过OLED板原理图可以看出OLED板SDA与底板TX、SCL与底板RX,底板左边TX对应核心板TXD1,底板左边RX对应核心板RXD1;陀螺仪数据手册参考https://gitee.com/HiSpark/hi3861_hdu_iot_application/issues/I6WPSS?from=project-issue 里面的陀螺仪.pdf;硬件搭建要求如图所示: + + 参考[核心板板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf)、[OLED板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_OLED_VER.A.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf) + + ![image-20240205104416249](../../../docs/pic/gyro/gyro4181.png) + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 板上小屏幕实时显示当前偏航角、俯仰角、横滚角。 + + ![image-20240205104416249](../../../docs/pic/gyro/gyro4182.png)![image-20240205104416249](../../../docs/pic/gyro/gyro4183.png) + +## 1.4 接口介绍 + +### 1.4.1 uapi_spi_init() + +| **定义:** | eerrcode_t uapi_spi_init(spi_bus_t bus, spi_attr_t *attr, spi_extra_attr_t *extra_attr); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 初始化 SPI | +| **参数:** | bus:指定的SPI接口
attr:SPI的基础配置参数
extra_attr:SPI的高级配置参数 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\spi.h | + +### 1.4.2 uapi_spi_master_write() + +| 定义: | errcode_t uapi_spi_master_write(spi_bus_t bus, const spi_xfer_data_t *data, uint32_t timeout); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 将数据从主机写入到从机。有两种方式,一种是手动切换模式,另外一种是自动切换模式,两种方式是静态配置的 手动切换方式一共有以下三种传输模式,但是不能在同一bus中同时使用。 | +| **参数:** | bus:指定的SPI接口
data:数据传输指针
timeout:当前传输的超时时间 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\spi.h | + +### 1.4.3 uapi_spi_master_read() + +| **定义:** | errcode_t uapi_spi_master_read(spi_bus_t bus, const spi_xfer_data_t *data, uint32_t timeout); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 从slave读取数据。有两种方式,一种是手动切换模式,另外一种是自动切换模式,两种方式是静态配置的。手动切换方式一共有以下三种传输模式,但是不能在同一bus中同时使用bus:I2C总线 | +| **参数:** | bus:指定的SPI接口
data:数据传输指针
timeout:当前传输的超时时间 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\spi.h | + +### 1.4.4 uapi_spi_master_writeread() + +| **定义:** | errcode_t uapi_spi_master_writeread(spi_bus_t bus, const spi_xfer_data_t *data, uint32_t timeout); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 主机写入和读取数据。有两种方式,一种是手动切换模式,另外一种是自动切换模式,两种方式是静态配置的。手动切换方式一共有以下两种种传输模式,但是不能在同一bus中同时使用。 | +| **参数:** | bus:指定的SPI接口
data:数据传输指针
timeout:当前传输的超时时间 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\spi.h | + +### 1.4.5 uapi_pin_set_mode() + +| **定义:** | errcode_t uapi_pin_set_mode(pin_t pin, pin_mode_t mode); | +| ------------ | -------------------------------------------------------- | +| **功能:** | 设置引脚复用模式 | +| **参数:** | pin:io
mode:复用模式 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pinctrl.h | + +### 1.4.6 ssd1306_SetCursor() + +| **定义:** | void ssd1306_SetCursor(uint8_t x, uint8_t y); | +| ------------ | --------------------------------------------- | +| **功能:** | 设置字符串显示位置 | +| **参数:** | x:横坐标
y:众坐标 | +| **返回值:** | 无返回值 | +| **依赖:** | oled\ssd1306.h | + +### 1.4.7 ssd1306_DrawString() + +| **定义:** | char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置输出的字符串 | +| **参数:** | str:要输出的字符串
Font:字符串大小
color:颜色 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | oled\ssd1306.h | + +### 1.4.8 ssd1306_UpdateScreen() + +| **定义:** | void ssd1306_UpdateScreen(void); | +| ------------ | -------------------------------- | +| **功能:** | 在屏幕显示字符串 | +| **参数:** | 无 | +| **返回值:** | 无 | +| **依赖:** | oled\ssd1306.h | + +## 1.5 具体实现 + + 步骤一:初始化I2C设备; + + 步骤二:I2C通信正常后,初始化OLED; + + 步骤三:通过数据手册中协议要求,发送数据 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”gyro“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\gyro文件里面内容拷贝到**步骤一创建的Sample文件夹中”gyro“**。 + + ![image-20240418095013956](../../../docs/pic/gyro/image-20240418095013956.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support ENVIRONMENT Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240418095038553 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七“软件烧录成功后,按一下开发板的RESET按键复位开发板,板上小屏幕实时显示当前偏航角、俯仰角、横滚角。 + + ![image-20240205104416249](../../../docs/pic/gyro/gyro4182.png)![image-20240205104416249](../../../docs/pic/gyro/gyro4183.png) \ No newline at end of file diff --git a/src/vendor/test/gyro/spi_master_gyro.c b/src/vendor/test/gyro/spi_master_gyro.c new file mode 100644 index 0000000000000000000000000000000000000000..faa162c006ae2f9c2bee7c25ab890800e377fbcd --- /dev/null +++ b/src/vendor/test/gyro/spi_master_gyro.c @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "math.h" +#include "pinctrl.h" +#include "spi.h" +#include "gpio.h" +#include "i2c.h" +#include "watchdog.h" +#include "osal_debug.h" +#include "soc_osal.h" +#include "app_init.h" +#include "ssd1306.h" +#include "spi_master_gyro.h" + +#define SPI_SLAVE_NUM 1 +#define SPI_BUS_CLK 32000000 +#define SPI_FREQUENCY 2 +#define SPI_CLK_POLARITY 1 +#define SPI_CLK_PHASE 1 +#define SPI_FRAME_FORMAT 0 +#define SPI_FRAME_FORMAT_STANDARD 0 +#define SPI_FRAME_SIZE_8 0x1f +#define SPI_TMOD 0 +#define SPI_WAIT_CYCLES 0x10 +#define CONFIG_SPI_DI_MASTER_PIN 11 +#define CONFIG_SPI_DO_MASTER_PIN 9 +#define CONFIG_SPI_CLK_MASTER_PIN 7 +#define CONFIG_SPI_CS_MASTER_PIN 8 +#define CONFIG_SPI_MASTER_PIN_MODE 3 +#define CONFIG_SPI_TRANSFER_LEN 2 +#define CONFIG_SPI_MASTER_BUS_ID 0 +#define CONFIG_I2C_SCL_MASTER_PIN 15 +#define CONFIG_I2C_SDA_MASTER_PIN 16 +#define CONFIG_I2C_MASTER_PIN_MODE 2 +#define I2C_SET_BANDRATE 400000 +#define I2C_MASTER_ADDR 0x0 + +#define SPI_TASK_STACK_SIZE 0x1000 +#define SPI_TASK_DURATION_MS 300 +#define SPI_TASK_PRIO 17 + +#define gyroKp (20.0f) // 比例增益支配率收敛到加速度计/磁强计 +#define gyroKi (0.0004f) // 积分增益支配率的陀螺仪偏见的衔接 +#define gyroHalfT (0.005f) // 采样周期的一半 +#define PAI 3.14 +#define DEGREES 180 + +float q0 = 1, q1 = 0, q2 = 0, q3 = 0; // 四元数的元素,代表估计方向 +float exInt = 0, eyInt = 0, ezInt = 0; // 按比例缩小积分误差 +float g_gyro_yaw, g_gyro_pitch, g_gyro_roll; // 偏航角,俯仰角,翻滚角 +static float yaw_conv = 0.0f; + +static void app_spi_init_pin(void) +{ + uapi_pin_set_mode(CONFIG_SPI_DI_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_SPI_DO_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_SPI_CLK_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_SPI_CS_MASTER_PIN, 0); + uapi_gpio_set_dir(CONFIG_SPI_CS_MASTER_PIN, GPIO_DIRECTION_OUTPUT); + uapi_gpio_set_val(CONFIG_SPI_CS_MASTER_PIN, GPIO_LEVEL_HIGH); +} + +static void app_i2c_init_pin(void) +{ + uapi_pin_set_mode(CONFIG_I2C_SCL_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_I2C_SDA_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE); +} + +static uint8_t gyro_spi_write_read(uint8_t addr, uint8_t writedata, uint8_t *rx_data) +{ + uint32_t ret = 0; + uint8_t tx_data[CONFIG_SPI_TRANSFER_LEN] = {addr, writedata}; + spi_xfer_data_t data = { + .tx_buff = tx_data, + .tx_bytes = CONFIG_SPI_TRANSFER_LEN, + .rx_buff = rx_data, + .rx_bytes = CONFIG_SPI_TRANSFER_LEN, + }; + uapi_gpio_set_val(CONFIG_SPI_CS_MASTER_PIN, GPIO_LEVEL_LOW); + + ret = uapi_spi_master_write(CONFIG_SPI_MASTER_BUS_ID, &data, 0xFFFFFFFF); + if (ret != 0) { + printf("spi = %0x master send failed\r\n", ret); + return ret; + } + ret = uapi_spi_master_read(CONFIG_SPI_MASTER_BUS_ID, &data, 0xFFFFFFFF); + if (ret != 0) { + printf("spi = %0x master read failed\r\n", ret); + return ret; + } + for (int i = 0; i < 2; i++) { + printf("%0x, readbuff[%d] = %0x\r\n", tx_data[0], i, data.rx_buff[i]); + } + uapi_gpio_set_val(CONFIG_SPI_CS_MASTER_PIN, GPIO_LEVEL_HIGH); + return data.rx_buff[1]; +} + +void IMU_YAW_CAL(float gyroZ) +{ + int ret = 0; + static char Pitchline[32] = {0}; + static char Rollline[32] = {0}; + static char Yawline[32] = {0}; + static float dt = 0.03; // 0.03代表300ms读取陀螺仪数据 + static float yaw = 0.0f, temp = 0.0f; +// 除去零偏 +#if 0 + static int a = 0; + a++; + if (hi_get_seconds() <= 5) { // 5s + printf("---------times-----------:%d\n", a); + } +#endif + if (fabs(gyroZ) < 0.04) { // 0.04标准值 + temp = 0; + } else { + temp = gyroZ * dt; + } + yaw += temp; + yaw_conv = yaw * 57.32; // 57.32 初始值 + // 360°一个循环 + if (fabs(yaw_conv) > 360.0f) { + if ((yaw_conv) < 0) { + yaw_conv += 360.0f; + } else { + yaw_conv -= 360.0f; + } + } + ssd1306_SetCursor(0, 15); // 0为横坐标,15为纵坐标 + ret = sprintf(Pitchline, "Pitch: %.2f", g_gyro_pitch); + if (ret < 0) { + printf("Pitch failed\r\n"); + } + ssd1306_DrawString(Pitchline, Font_7x10, White); + ssd1306_SetCursor(0, 30); // 0为横坐标,30为纵坐标 + ret = sprintf(Rollline, "roll: %.2f", g_gyro_roll); + if (ret < 0) { + printf("roll failed\r\n"); + } + ssd1306_DrawString(Rollline, Font_7x10, White); + ssd1306_SetCursor(0, 0); // 0为横坐标,0为纵坐标 + ret = sprintf(Yawline, "roll: %.2f", yaw_conv); + if (ret < 0) { + printf("yaw failed\r\n"); + } + ssd1306_DrawString(Yawline, Font_7x10, White); + ssd1306_UpdateScreen(); +} + +void GetRoll(float atan2x, float atan2y) +{ + float atan2_x = atan2x; + float atan2_y = atan2y; + if (atan2_x > 0) { + g_gyro_roll = atan(atan2_y / atan2_x) * DEGREES / PAI; + } else if (atan2_x < 0 && atan2_y >= 0) { + g_gyro_roll = atan(atan2_y / atan2_x) * DEGREES / PAI + DEGREES; + } else if (atan2_x < 0 && atan2_y < 0) { + g_gyro_roll = atan(atan2_y / atan2_x) * DEGREES / PAI - DEGREES; + } else if (atan2_y > 0 && atan2_x == 0) { + g_gyro_roll = 90; // 90° + } else if (atan2_y < 0 && atan2_x == 0) { + g_gyro_roll = -90; // -90° + } else { + printf("undefined\n"); + } +} + +void GetPitch(float atan2x, float atan2y) +{ + float atan2_x = atan2x; + float atan2_y_pitch = atan2y; + if (atan2_x > 0) { + g_gyro_pitch = atan(atan2_y_pitch / atan2_x) * DEGREES / PAI; + } else if (atan2_x < 0 && atan2_y_pitch >= 0) { + g_gyro_pitch = atan(atan2_y_pitch / atan2_x) * DEGREES / PAI + DEGREES; + } else if (atan2_x < 0 && atan2_y_pitch < 0) { + g_gyro_pitch = atan(atan2_y_pitch / atan2_x) * DEGREES / PAI - DEGREES; + } else if (atan2_y_pitch > 0 && atan2_x == 0) { + g_gyro_pitch = 90; // 90° + } else if (atan2_y_pitch < 0 && atan2_x == 0) { + g_gyro_pitch = -90; // -90° + } else { + printf("undefined\n"); + } +} + +void IMU_Attitude_cal(float gcx, float gcy, float gcz, float acx, float acy, float acz) +{ + float norm; + float vx, vy, vz; + float ex, ey, ez; + float atan2_x, atan2_y; + float atan2_y_pitch; + float ax = acx, ay = acy, az = acz; + float gx = gcx, gy = gcy, gz = gcz; + + // 把采集到的三轴加速度转化为单位向量,即向量除以模 + norm = (float)sqrt((float)(ax * ax + ay * ay + az * az)); + if (norm == 0) { + printf("209 norm = 0,failed\n"); + } + ax = ax / norm; + ay = ay / norm; + az = az / norm; + + // 把四元素换算成方向余弦中的第三行的三个元素 + // vx、vy、vz其实就是上一次的欧拉角(四元数)机体参考坐标系换算出来的重力的单位向量 + vx = 2 * (q1 * q3 - q0 * q2); // 2计算系数 + vy = 2 * (q0 * q1 + q2 * q3); // 2计算系数 + vz = q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3; + + // 对向量叉乘,求出姿态误差 + // ex、ey、ez为三轴误差元素 + ex = (ay * vz - az * vy); + ey = (az * vx - ax * vz); + ez = (ax * vy - ay * vx); + + // 叉乘向量仍旧是机体坐标系上的,而陀螺仪积分误差也是机体坐标系 + // 而且叉积的大小与陀螺仪误差成正比,正好拿来纠正陀螺 + exInt = exInt + ex * gyroKi; + eyInt = eyInt + ey * gyroKi; + ezInt = ezInt + ez * gyroKi; + + // 调整后的陀螺仪测量 + gx = gx + gyroKp * ex + exInt; + gy = gy + gyroKp * ey + eyInt; + gz = gz + gyroKp * ez + ezInt; + + // 使用一阶龙格库塔解四元数微分方程 + q0 = q0 + (-q1 * gx - q2 * gy - q3 * gz) * gyroHalfT; + q1 = q1 + (q0 * gx + q2 * gz - q3 * gy) * gyroHalfT; + q2 = q2 + (q0 * gy - q1 * gz + q3 * gx) * gyroHalfT; + q3 = q3 + (q0 * gz + q1 * gy - q2 * gx) * gyroHalfT; + + // 四元数归一化 + norm = sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3); + if (norm == 0) { + printf("247 norm = 0,failed\n"); + } + q0 = q0 / norm; + q1 = q1 / norm; + q2 = q2 / norm; + q3 = q3 / norm; + + // 计算姿态角,本文Roll为横滚角,Pitch为俯仰角 + atan2_x = -2 * q1 * q1 - 2 * q2 * q2 + 1; // 2 计算参数 + atan2_y = 2 * q2 * q3 + 2 * q0 * q1; // 2 计算参数 + GetRoll(atan2_x, atan2_y); + // 俯仰角 + atan2_y_pitch = -2 * q1 * q3 + 2 * q0 * q2; // 2 计算参数 + GetPitch(atan2_x, atan2_y_pitch); +} + +void Lsm_Get_RawAcc(void) +{ + unsigned char buf[12] = {0}; + short acc_x = 0, acc_y = 0, acc_z = 0; + float acc_x_conv = 0, acc_y_conv = 0, acc_z_conv = 0; + short ang_rate_x = 0, ang_rate_y = 0, ang_rate_z = 0; + float ang_rate_x_conv = 0, ang_rate_y_conv = 0, ang_rate_z_conv = 0; + unsigned char read_buff[2] = {0}; + if ((gyro_spi_write_read(LSM6DSL_STATUS_REG | SPI_READ, 0xff, read_buff) & 0x01) != 0) { + buf[0] = gyro_spi_write_read(LSM6DSL_OUTX_H_XL | SPI_READ, 0xff, read_buff); + buf[1] = gyro_spi_write_read(LSM6DSL_OUTX_L_XL | SPI_READ, 0xff, read_buff); + buf[2] = gyro_spi_write_read(LSM6DSL_OUTY_H_XL | SPI_READ, 0xff, read_buff); + buf[3] = gyro_spi_write_read(LSM6DSL_OUTY_L_XL | SPI_READ, 0xff, read_buff); + buf[4] = gyro_spi_write_read(LSM6DSL_OUTZ_H_XL | SPI_READ, 0xff, read_buff); + buf[5] = gyro_spi_write_read(LSM6DSL_OUTZ_L_XL | SPI_READ, 0xff, read_buff); + + buf[6] = gyro_spi_write_read(LSM6DSL_OUTX_H_G | SPI_READ, 0xff, read_buff); + buf[7] = gyro_spi_write_read(LSM6DSL_OUTX_L_G | SPI_READ, 0xff, read_buff); + buf[8] = gyro_spi_write_read(LSM6DSL_OUTY_H_G | SPI_READ, 0xff, read_buff); + buf[9] = gyro_spi_write_read(LSM6DSL_OUTY_L_G | SPI_READ, 0xff, read_buff); + buf[10] = gyro_spi_write_read(LSM6DSL_OUTZ_H_G | SPI_READ, 0xff, read_buff); + buf[11] = gyro_spi_write_read(LSM6DSL_OUTZ_L_G | SPI_READ, 0xff, read_buff); + + ang_rate_x = (buf[6] << 8) | buf[7]; // 将buff6 右移8位在与上buff 7 + ang_rate_y = (buf[8] << 8) | buf[9]; // 将buff8 右移8位在与上buff 9 + ang_rate_z = (buf[10] << 8) | buf[11]; // 将buff10 右移8位在与上buff 11 + + acc_x = (buf[0] << 8) | buf[1]; // 将buff0 右移8位在与上buff 1 + acc_y = (buf[2] << 8) | buf[3]; // 将buff2 右移8位在与上buff 3 + acc_z = (buf[4] << 8) | buf[5]; // 将buff4 右移8位在与上buff 5 + + ang_rate_x_conv = PAI / 180.0 * ang_rate_x / 14.29; // 180.0代表度数 14.29量程 + ang_rate_y_conv = PAI / 180.0 * ang_rate_y / 14.29; // 180.0代表度数 14.29量程 + ang_rate_z_conv = PAI / 180.0 * ang_rate_z / 14.29; // 180.0代表度数 14.29量程 + + acc_x_conv = acc_x / 4098.36; // 4098.36量程 + acc_y_conv = acc_y / 4098.36; // 4098.36量程 + acc_z_conv = acc_z / 4098.36; // 4098.36量程 + IMU_Attitude_cal(ang_rate_x_conv, ang_rate_y_conv, ang_rate_z_conv, acc_x_conv, acc_y_conv, acc_z_conv); + IMU_YAW_CAL(ang_rate_z_conv); + } +} + +void Lsm6d3s_Init(void) +{ + uint8_t read_buff[CONFIG_SPI_TRANSFER_LEN] = {0}; + gyro_spi_write_read(LSM6DSL_CTRL3_C, 0x34, read_buff); + gyro_spi_write_read(LSM6DSL_CTRL2_G, 0X4C, read_buff); + gyro_spi_write_read(LSM6DSL_CTRL10_C, 0x38, read_buff); + gyro_spi_write_read(LSM6DSL_CTRL1_XL, 0x4F, read_buff); + gyro_spi_write_read(LSM6DSL_TAP_CFG, 0x10, read_buff); + gyro_spi_write_read(LSM6DSL_WAKE_UP_DUR, 0x00, read_buff); + gyro_spi_write_read(LSM6DSL_WAKE_UP_THS, 0x02, read_buff); + gyro_spi_write_read(LSM6DSL_TAP_THS_6D, 0x40, read_buff); + gyro_spi_write_read(LSM6DSL_CTRL8_XL, 0x01, read_buff); +} + +static void app_spi_master_init_config(void) +{ + spi_attr_t config = {0}; + spi_extra_attr_t ext_config = {0}; + + config.is_slave = false; + config.slave_num = SPI_SLAVE_NUM; + config.bus_clk = SPI_BUS_CLK; + config.freq_mhz = SPI_FREQUENCY; + config.clk_polarity = SPI_CLK_POLARITY; + config.clk_phase = SPI_CLK_PHASE; + config.frame_format = SPI_FRAME_FORMAT; + config.spi_frame_format = HAL_SPI_FRAME_FORMAT_STANDARD; + // config.frame_size = SPI_FRAME_SIZE_8; // 80001338代表发送数据的格式不对,需要修改配置参数 + config.frame_size = HAL_SPI_FRAME_SIZE_8; + config.tmod = SPI_TMOD; + config.sste = 1; + + ext_config.qspi_param.wait_cycles = SPI_WAIT_CYCLES; + int ret = uapi_spi_init(CONFIG_SPI_MASTER_BUS_ID, &config, &ext_config); + if (ret != 0) { + printf("spi init fail %0x\r\n", ret); + } +} + +static void app_i2c_master_init_config(void) +{ + uint32_t baudrate = I2C_SET_BANDRATE; + uint32_t hscode = I2C_MASTER_ADDR; + errcode_t ret = uapi_i2c_master_init(1, baudrate, hscode); + if (ret != 0) { + printf("i2c init failed, ret = %0x\r\n", ret); + } +} + +void *spi_gyro_task(void) +{ + uapi_watchdog_disable(); + app_i2c_init_pin(); + app_spi_init_pin(); + app_i2c_master_init_config(); + app_spi_master_init_config(); + ssd1306_Init(); + ssd1306_Fill(Black); + uint8_t read_buff[CONFIG_SPI_TRANSFER_LEN] = {0}; + while (gyro_spi_write_read(LSM6DSL_WHO_AM_I | SPI_READ, 0xff, read_buff) != 0x6a) { + osal_mdelay(SPI_TASK_DURATION_MS); // 等待IMU上电复位成功 + } + Lsm6d3s_Init(); + while (1) { + osal_mdelay(1); + Lsm_Get_RawAcc(); + } + return 0; +} + +static void spi_master_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)spi_gyro_task, 0, "spi_gyro_task", SPI_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, SPI_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the spi_master_entry. */ +app_run(spi_master_entry); \ No newline at end of file diff --git a/src/vendor/test/gyro/spi_master_gyro.h b/src/vendor/test/gyro/spi_master_gyro.h new file mode 100644 index 0000000000000000000000000000000000000000..b73bb018cae4f00865eef2c91ab09645bcd4e386 --- /dev/null +++ b/src/vendor/test/gyro/spi_master_gyro.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 SPI_MASTER_GYRO_H +#define SPI_MASTER_GYRO_H + +#define SPI_READ ((unsigned char)0x80) +#define SPI_WRITE ((unsigned char)0x00) + +/* sensor output data */ +#define LSM6DSL_OUTX_L_G 0X22 +#define LSM6DSL_OUTX_H_G 0X23 +#define LSM6DSL_OUTY_L_G 0X24 +#define LSM6DSL_OUTY_H_G 0X25 +#define LSM6DSL_OUTZ_L_G 0X26 +#define LSM6DSL_OUTZ_H_G 0X27 + +#define LSM6DSL_OUTX_L_XL 0X28 +#define LSM6DSL_OUTX_H_XL 0X29 +#define LSM6DSL_OUTY_L_XL 0X2A +#define LSM6DSL_OUTY_H_XL 0X2B +#define LSM6DSL_OUTZ_L_XL 0X2C +#define LSM6DSL_OUTZ_H_XL 0X2D +/* sensor control reg */ +#define LSM6DSL_CTRL1_XL 0X10 +#define LSM6DSL_CTRL2_G 0X11 +#define LSM6DSL_CTRL3_C 0X12 +#define LSM6DSL_CTRL8_XL 0X17 +#define LSM6DSL_CTRL9_XL 0X18 +#define LSM6DSL_CTRL10_C 0X19 +#define LSM6DSL_INT2_CTRL 0X0E +#define LSM6DSL_WHO_AM_I 0x0F // get id +#define LSM6DSL_STATUS_REG 0x1E + +#define LSM6DSL_SENSORHUB11_REG 0X38 +#define LSM6DSL_TAP_CFG 0X58 +#define LSM6DSL_TAP_THS_6D 0X59 +#define LSM6DSL_INT_DUR2 0X5A +#define LSM6DSL_WAKE_UP_THS 0X5B +#define LSM6DSL_WAKE_UP_DUR 0X5C +#define LSM6DSL_FREE_FALL 0X5D +#define LSM6DSL_MD1_CFG 0X5E + +void *spi_gyro_task(void); + +#endif diff --git a/src/vendor/test/gyro/ssd1306.c b/src/vendor/test/gyro/ssd1306.c new file mode 100644 index 0000000000000000000000000000000000000000..e7c4dab13006eb2a6cfd7513fa37f76b2489776e --- /dev/null +++ b/src/vendor/test/gyro/ssd1306.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 +#include +#include +#include +#include +#include +#include +#include "i2c.h" +#include "soc_osal.h" +#include "ssd1306.h" + +#define CONFIG_I2C_MASTER_BUS_ID 1 +#define I2C_SLAVE2_ADDR 0x3C +#define SSD1306_CTRL_CMD 0x00 +#define SSD1306_CTRL_DATA 0x40 +#define SSD1306_MASK_CONT (0x1 << 7) +#define DOUBLE 2 + +void ssd1306_Reset(void) +{ + // Wait for the screen to boot,1ms The delay here is very important + osal_mdelay(1); +} + +static uint32_t ssd1306_SendData(uint8_t *buffer, uint32_t size) +{ + uint16_t dev_addr = I2C_SLAVE2_ADDR; + i2c_data_t data = {0}; + data.send_buf = buffer; + data.send_len = size; + uint32_t retval = uapi_i2c_master_write(CONFIG_I2C_MASTER_BUS_ID, dev_addr, &data); + if (retval != 0) { + printf("I2cWrite(%02X) failed, %0X!\n", data.send_buf[1], retval); + return retval; + } + return 0; +} + +static uint32_t ssd1306_WiteByte(uint8_t regAddr, uint8_t byte) +{ + uint8_t buffer[] = {regAddr, byte}; + return ssd1306_SendData(buffer, sizeof(buffer)); +} + +// Send a byte to the command register +void ssd1306_WriteCommand(uint8_t byte) +{ + ssd1306_WiteByte(SSD1306_CTRL_CMD, byte); +} + +// Send data +void ssd1306_WriteData(uint8_t *buffer, uint32_t buff_size) +{ + uint8_t data[SSD1306_WIDTH * DOUBLE] = {0}; + for (uint32_t i = 0; i < buff_size; i++) { + data[i * DOUBLE] = SSD1306_CTRL_DATA | SSD1306_MASK_CONT; + data[i * DOUBLE + 1] = buffer[i]; + } + data[(buff_size - 1) * DOUBLE] = SSD1306_CTRL_DATA; + ssd1306_SendData(data, sizeof(data)); +} + +// Screenbuffer +static uint8_t SSD1306_Buffer[SSD1306_BUFFER_SIZE]; + +// Screen object +static SSD1306_t SSD1306; + +/* Fills the Screenbuffer with values from a given buffer of a fixed length */ +SSD1306_Error_t ssd1306_FillBuffer(uint8_t *buf, uint32_t len) +{ + SSD1306_Error_t ret = SSD1306_ERR; + if (len <= SSD1306_BUFFER_SIZE) { + memcpy_s(SSD1306_Buffer, len + 1, buf, len); + ret = SSD1306_OK; + } + return ret; +} + +void ssd1306_Init_CMD(void) +{ + ssd1306_WriteCommand(0xA4); // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content + + ssd1306_WriteCommand(0xD3); // -set display offset - CHECK + ssd1306_WriteCommand(0x00); // -not offset + + ssd1306_WriteCommand(0xD5); // --set display clock divide ratio/oscillator frequency + ssd1306_WriteCommand(0xF0); // --set divide ratio + + ssd1306_WriteCommand(0xD9); // --set pre-charge period + ssd1306_WriteCommand(0x11); // 0x22 by default + + ssd1306_WriteCommand(0xDA); // --set com pins hardware configuration - CHECK +#if (SSD1306_HEIGHT == 32) + ssd1306_WriteCommand(0x02); +#elif (SSD1306_HEIGHT == 64) + ssd1306_WriteCommand(0x12); +#elif (SSD1306_HEIGHT == 128) + ssd1306_WriteCommand(0x12); +#else +#error "Only 32, 64, or 128 lines of height are supported!" +#endif + + ssd1306_WriteCommand(0xDB); // --set vcomh + ssd1306_WriteCommand(0x30); // 0x20,0.77xVcc, 0x30,0.83xVcc + + ssd1306_WriteCommand(0x8D); // --set DC-DC enable + ssd1306_WriteCommand(0x14); // + ssd1306_SetDisplayOn(1); // --turn on SSD1306 panel +} + +// Initialize the oled screen +void ssd1306_Init(void) +{ + // Reset OLED + ssd1306_Reset(); + // Init OLED + ssd1306_SetDisplayOn(0); // display off + + ssd1306_WriteCommand(0x20); // Set Memory Addressing Mode + ssd1306_WriteCommand(0x00); // 00b,Horizontal Addressing Mode; 01b,Vertical Addressing Mode; + // 10b,Page Addressing Mode (RESET); 11b,Invalid + + ssd1306_WriteCommand(0xB0); // Set Page Start Address for Page Addressing Mode,0-7 + +#ifdef SSD1306_MIRROR_VERT + ssd1306_WriteCommand(0xC0); // Mirror vertically +#else + ssd1306_WriteCommand(0xC8); // Set COM Output Scan Direction +#endif + + ssd1306_WriteCommand(0x00); // ---set low column address + ssd1306_WriteCommand(0x10); // ---set high column address + + ssd1306_WriteCommand(0x40); // --set start line address - CHECK + + ssd1306_SetContrast(0xFF); + +#ifdef SSD1306_MIRROR_HORIZ + ssd1306_WriteCommand(0xA0); // Mirror horizontally +#else + ssd1306_WriteCommand(0xA1); // --set segment re-map 0 to 127 - CHECK +#endif + +#ifdef SSD1306_INVERSE_COLOR + ssd1306_WriteCommand(0xA7); // --set inverse color +#else + ssd1306_WriteCommand(0xA6); // --set normal color +#endif + +// Set multiplex ratio. +#if (SSD1306_HEIGHT == 128) + // Found in the Luma Python lib for SH1106. + ssd1306_WriteCommand(0xFF); +#else + ssd1306_WriteCommand(0xA8); // --set multiplex ratio(1 to 64) - CHECK +#endif + +#if (SSD1306_HEIGHT == 32) + ssd1306_WriteCommand(0x1F); // +#elif (SSD1306_HEIGHT == 64) + ssd1306_WriteCommand(0x3F); // +#elif (SSD1306_HEIGHT == 128) + ssd1306_WriteCommand(0x3F); // Seems to work for 128px high displays too. +#else +#error "Only 32, 64, or 128 lines of height are supported!" +#endif + ssd1306_Init_CMD(); + // Clear screen + ssd1306_Fill(Black); + + // Flush buffer to screen + ssd1306_UpdateScreen(); + + // Set default values for screen object + SSD1306.CurrentX = 0; + SSD1306.CurrentY = 0; + + SSD1306.Initialized = 1; +} + +// Fill the whole screen with the given color +void ssd1306_Fill(SSD1306_COLOR color) +{ + /* Set memory */ + uint32_t i; + + for (i = 0; i < sizeof(SSD1306_Buffer); i++) { + SSD1306_Buffer[i] = (color == Black) ? 0x00 : 0xFF; + } +} + +// Write the screenbuffer with changed to the screen +void ssd1306_UpdateScreen(void) +{ + // Write data to each page of RAM. Number of pages + // depends on the screen height: + // + // * 32px == 4 pages + // * 64px == 8 pages + // * 128px == 16 pages + + uint8_t cmd[] = { + 0X21, // 设置列起始和结束地址 + 0X00, // 列起始地址 0 + 0X7F, // 列终止地址 127 + 0X22, // 设置页起始和结束地址 + 0X00, // 页起始地址 0 + 0X07, // 页终止地址 7 + }; + uint32_t count = 0; + uint8_t data[sizeof(cmd) * DOUBLE + SSD1306_BUFFER_SIZE + 1] = {}; + + // copy cmd + for (uint32_t i = 0; i < sizeof(cmd) / sizeof(cmd[0]); i++) { + data[count++] = SSD1306_CTRL_CMD | SSD1306_MASK_CONT; + data[count++] = cmd[i]; + } + + // copy frame data + data[count++] = SSD1306_CTRL_DATA; + memcpy_s(&data[count], SSD1306_BUFFER_SIZE + 1, SSD1306_Buffer, SSD1306_BUFFER_SIZE); + count += sizeof(SSD1306_Buffer); + + // send to i2c bus + uint32_t retval = ssd1306_SendData(data, count); + if (retval != 0) { + printf("ssd1306_UpdateScreen send frame data filed: %d!\r\n", retval); + } +} + +// Draw one pixel in the screenbuffer +// X => X Coordinate +// Y => Y Coordinate +// color => Pixel color +void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color) +{ + if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) { + // Don't write outside the buffer + return; + } + SSD1306_COLOR color1 = color; + // Check if pixel should be inverted + if (SSD1306.Inverted) { + color1 = (SSD1306_COLOR)!color1; + } + + // Draw in the right color + uint32_t c = 8; // 8 + if (color == White) { + SSD1306_Buffer[x + (y / c) * SSD1306_WIDTH] |= 1 << (y % c); + } else { + SSD1306_Buffer[x + (y / c) * SSD1306_WIDTH] &= ~(1 << (y % c)); + } +} + +// Draw 1 char to the screen buffer +// ch => char om weg te schrijven +// Font => Font waarmee we gaan schrijven +// color => Black or White +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color) +{ + uint32_t i, b, j; + + // Check if character is valid + uint32_t ch_min = 32; // 32 + uint32_t ch_max = 126; // 126 + if ((uint32_t)ch < ch_min || (uint32_t)ch > ch_max) { + return 0; + } + + // Check remaining space on current line + if (SSD1306_WIDTH < (SSD1306.CurrentX + Font.FontWidth) || SSD1306_HEIGHT < (SSD1306.CurrentY + Font.FontHeight)) { + // Not enough space on current line + return 0; + } + + // Use the font to write + for (i = 0; i < Font.FontHeight; i++) { + b = Font.data[(ch - ch_min) * Font.FontHeight + i]; + for (j = 0; j < Font.FontWidth; j++) { + if ((b << j) & 0x8000) { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)color); + } else { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color); + } + } + } + + // The current space is now taken + SSD1306.CurrentX += Font.FontWidth; + + // Return written char for validation + return ch; +} + +// Write full string to screenbuffer +char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color) +{ + // Write until null-byte + char *str1 = str; + while (*str1) { + if (ssd1306_DrawChar(*str1, Font, color) != *str1) { + // Char could not be written + return *str1; + } + // Next char + str1++; + } + + // Everything ok + return *str1; +} + +// Position the cursor +void ssd1306_SetCursor(uint8_t x, uint8_t y) +{ + SSD1306.CurrentX = x; + SSD1306.CurrentY = y; +} + +// Draw line by Bresenhem's algorithm +void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) +{ + uint8_t x = x1; + uint8_t y = y1; + int32_t deltaX = abs(x2 - x1); + int32_t deltaY = abs(y2 - y1); + int32_t signX = ((x1 < x2) ? 1 : -1); + int32_t signY = ((y1 < y2) ? 1 : -1); + int32_t error = deltaX - deltaY; + int32_t error2; + ssd1306_DrawPixel(x2, y2, color); + while ((x1 != x2) || (y1 != y2)) { + ssd1306_DrawPixel(x1, y1, color); + error2 = error * DOUBLE; + if (error2 > -deltaY) { + error -= deltaY; + x += signX; + } else { + /* nothing to do */ + } + if (error2 < deltaX) { + error += deltaX; + y += signY; + } else { + /* nothing to do */ + } + } +} + +// Draw polyline +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color) +{ + uint16_t i; + if (par_vertex != 0) { + for (i = 1; i < par_size; i++) { + ssd1306_DrawLine(par_vertex[i - 1].x, par_vertex[i - 1].y, par_vertex[i].x, par_vertex[i].y, color); + } + } else { + /* nothing to do */ + } + return; +} + +// Draw circle by Bresenhem's algorithm +void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color) +{ + int32_t x = -par_r; + int32_t y = 0; + int32_t b = 2; + int32_t err = b - b * par_r; + int32_t e2; + + if (par_x >= SSD1306_WIDTH || par_y >= SSD1306_HEIGHT) { + return; + } + + do { + ssd1306_DrawPixel(par_x - x, par_y + y, par_color); + ssd1306_DrawPixel(par_x + x, par_y + y, par_color); + ssd1306_DrawPixel(par_x + x, par_y - y, par_color); + ssd1306_DrawPixel(par_x - x, par_y - y, par_color); + e2 = err; + if (e2 <= y) { + y++; + err = err + (y * b + 1); + if (-x == y && e2 <= x) { + e2 = 0; + } else { + /* nothing to do */ + } + } else { + /* nothing to do */ + } + if (e2 > x) { + x++; + err = err + (x * b + 1); + } else { + /* nothing to do */ + } + } while (x <= 0); + + return; +} + +// Draw rectangle +void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) +{ + ssd1306_DrawLine(x1, y1, x2, y1, color); + ssd1306_DrawLine(x2, y1, x2, y2, color); + ssd1306_DrawLine(x2, y2, x1, y2, color); + ssd1306_DrawLine(x1, y2, x1, y1, color); +} + +void ssd1306_DrawBitmap(const uint8_t *bitmap, uint32_t size) +{ + unsigned int c = 8; + uint8_t rows = size * c / SSD1306_WIDTH; + if (rows > SSD1306_HEIGHT) { + rows = SSD1306_HEIGHT; + } + for (uint8_t y = 0; y < rows; y++) { + for (uint8_t x = 0; x < SSD1306_WIDTH; x++) { + uint8_t byte = bitmap[(y * SSD1306_WIDTH / c) + (x / c)]; + uint8_t bit = byte & (0x80 >> (x % c)); + ssd1306_DrawPixel(x, y, bit ? White : Black); + } + } +} + +void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data, uint32_t size) +{ + uint32_t stride = w; + uint8_t h = w; // 字体宽高一样 + uint8_t width = w; + if (x + w > SSD1306_WIDTH || y + h > SSD1306_HEIGHT || w * h == 0) { + printf("%dx%d @ %d,%d out of range or invalid!\r\n", w, h, x, y); + return; + } + + width = (width <= SSD1306_WIDTH ? width : SSD1306_WIDTH); + h = (h <= SSD1306_HEIGHT ? h : SSD1306_HEIGHT); + stride = (stride == 0 ? w : stride); + unsigned int c = 8; + + uint8_t rows = size * c / stride; + for (uint8_t i = 0; i < rows; i++) { + uint32_t base = i * stride / c; + for (uint8_t j = 0; j < width; j++) { + uint32_t idx = base + (j / c); + uint8_t byte = idx < size ? data[idx] : 0; + uint8_t bit = byte & (0x80 >> (j % c)); + ssd1306_DrawPixel(x + j, y + i, bit ? White : Black); + } + } +} + +void ssd1306_SetContrast(const uint8_t value) +{ + const uint8_t kSetContrastControlRegister = 0x81; + ssd1306_WriteCommand(kSetContrastControlRegister); + ssd1306_WriteCommand(value); +} + +void ssd1306_SetDisplayOn(const uint8_t on) +{ + uint8_t value; + if (on) { + value = 0xAF; // Display on + SSD1306.DisplayOn = 1; + } else { + value = 0xAE; // Display off + SSD1306.DisplayOn = 0; + } + ssd1306_WriteCommand(value); +} + +uint8_t ssd1306_GetDisplayOn(void) +{ + return SSD1306.DisplayOn; +} + +int g_ssd1306_current_loc_v = 0; +#define SSD1306_INTERVAL_V (15) + +void ssd1306_ClearOLED(void) +{ + ssd1306_Fill(Black); + g_ssd1306_current_loc_v = 0; +} + +void ssd1306_printf(char *fmt, ...) +{ + char buffer[20]; + int ret = 0; + if (fmt) { + va_list argList; + va_start(argList, fmt); + ret = vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), fmt, argList); + if (ret < 0) { + printf("buffer is null\r\n"); + } + va_end(argList); + ssd1306_SetCursor(0, g_ssd1306_current_loc_v); + ssd1306_DrawString(buffer, Font_7x10, White); + + ssd1306_UpdateScreen(); + } + g_ssd1306_current_loc_v += SSD1306_INTERVAL_V; +} diff --git a/src/vendor/test/gyro/ssd1306.h b/src/vendor/test/gyro/ssd1306.h new file mode 100644 index 0000000000000000000000000000000000000000..769f19c7af3a3aaf0f6fd007d62721c007b0e7d1 --- /dev/null +++ b/src/vendor/test/gyro/ssd1306.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 SSD1306_H +#define SSD1306_H + +#include +#include +#include "ssd1306_fonts.h" + +// SSD1306 OLED height in pixels +#ifndef SSD1306_HEIGHT +#define SSD1306_HEIGHT 64 +#endif + +// SSD1306 width in pixels +#ifndef SSD1306_WIDTH +#define SSD1306_WIDTH 128 +#endif + +// some LEDs don't display anything in first two columns + +#ifndef SSD1306_BUFFER_SIZE +#define SSD1306_BUFFER_SIZE (SSD1306_WIDTH * SSD1306_HEIGHT / 8) +#endif + +// Enumeration for screen colors +typedef enum { + Black = 0x00, // Black color, no pixel + White = 0x01 // Pixel is set. Color depends on OLED +} SSD1306_COLOR; + +typedef enum { + SSD1306_OK = 0x00, + SSD1306_ERR = 0x01 // Generic error. +} SSD1306_Error_t; + +// Struct to store transformations +typedef struct { + uint16_t CurrentX; + uint16_t CurrentY; + uint8_t Inverted; + uint8_t Initialized; + uint8_t DisplayOn; +} SSD1306_t; +typedef struct { + uint8_t x; + uint8_t y; +} SSD1306_VERTEX; + +// Procedure definitions +void ssd1306_Init(void); +void ssd1306_Fill(SSD1306_COLOR color); +void ssd1306_SetCursor(uint8_t x, uint8_t y); +void ssd1306_UpdateScreen(void); + +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color); +char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color); + +void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color); +void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color); +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color); +void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color); +void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color); +void ssd1306_DrawBitmap(const uint8_t *bitmap, uint32_t size); +void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data, uint32_t size); + +/** + * @brief Sets the contrast of the display. + * @param[in] value contrast to set. + * @note Contrast increases as the value increases. + * @note RESET = 7Fh. + */ +void ssd1306_SetContrast(const uint8_t value); +/** + * @brief Set Display ON/OFF. + * @param[in] on 0 for OFF, any for ON. + */ +void ssd1306_SetDisplayOn(const uint8_t on); +/** + * @brief Reads DisplayOn state. + * @return 0: OFF. + * 1: ON. + */ +uint8_t ssd1306_GetDisplayOn(void); + +// Low-level procedures +void ssd1306_Reset(void); +void ssd1306_WriteCommand(uint8_t byte); +void ssd1306_WriteData(uint8_t *buffer, size_t buff_size); +SSD1306_Error_t ssd1306_FillBuffer(uint8_t *buf, uint32_t len); +void ssd1306_ClearOLED(void); +void ssd1306_printf(char *fmt, ...); + +#endif // __SSD1306_H__ \ No newline at end of file diff --git a/src/vendor/test/gyro/ssd1306_fonts.c b/src/vendor/test/gyro/ssd1306_fonts.c new file mode 100644 index 0000000000000000000000000000000000000000..8053265cdef8a0474cc3506121ce65c54cc06d6f --- /dev/null +++ b/src/vendor/test/gyro/ssd1306_fonts.c @@ -0,0 +1,819 @@ +/* + MIT License + + Copyright (c) 2018-2019, Alexey Dynda + + 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. +*/ +/* + * ssd1306xled_font6x8 is by Neven Boyanov + * ssd1306xled_font8x16 is by Neven Boyanov + * + * @created: 2014-08-12 + * @author: Neven Boyanov + * + * Copyright (c) 2015 Neven Boyanov, Tinusaur Team. All Rights Reserved. + * Distributed as open source software under MIT License, see LICENSE.txt file. + * Please, as a favour, retain the link http://tinusaur.org to The Tinusaur Project. + * + * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled + * + */ + +#include "ssd1306_fonts.h" + +/************************************6*8的点阵************************************/ +const unsigned char g_f6X8[][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // sp + {0x00, 0x00, 0x00, 0x2f, 0x00, 0x00}, // ! + {0x00, 0x00, 0x07, 0x00, 0x07, 0x00}, // " + {0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14}, // # + {0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12}, // $ + {0x00, 0x62, 0x64, 0x08, 0x13, 0x23}, // % + {0x00, 0x36, 0x49, 0x55, 0x22, 0x50}, // & + {0x00, 0x00, 0x05, 0x03, 0x00, 0x00}, // ' + {0x00, 0x00, 0x1c, 0x22, 0x41, 0x00}, // ( + {0x00, 0x00, 0x41, 0x22, 0x1c, 0x00}, // ) + {0x00, 0x14, 0x08, 0x3E, 0x08, 0x14}, // * + {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // + + {0x00, 0x00, 0x00, 0xA0, 0x60, 0x00}, // , + {0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // - + {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // . + {0x00, 0x20, 0x10, 0x08, 0x04, 0x02}, // / + {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0 + {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00}, // 1 + {0x00, 0x42, 0x61, 0x51, 0x49, 0x46}, // 2 + {0x00, 0x21, 0x41, 0x45, 0x4B, 0x31}, // 3 + {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10}, // 4 + {0x00, 0x27, 0x45, 0x45, 0x45, 0x39}, // 5 + {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6 + {0x00, 0x01, 0x71, 0x09, 0x05, 0x03}, // 7 + {0x00, 0x36, 0x49, 0x49, 0x49, 0x36}, // 8 + {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E}, // 9 + {0x00, 0x00, 0x36, 0x36, 0x00, 0x00}, // : + {0x00, 0x00, 0x56, 0x36, 0x00, 0x00}, // ;号 + {0x00, 0x08, 0x14, 0x22, 0x41, 0x00}, // < + {0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // = + {0x00, 0x00, 0x41, 0x22, 0x14, 0x08}, // > + {0x00, 0x02, 0x01, 0x51, 0x09, 0x06}, // ? + {0x00, 0x32, 0x49, 0x59, 0x51, 0x3E}, // @ + {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C}, // A + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36}, // B + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22}, // C + {0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C}, // D + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41}, // E + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01}, // F + {0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A}, // G + {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F}, // H + {0x00, 0x00, 0x41, 0x7F, 0x41, 0x00}, // I + {0x00, 0x20, 0x40, 0x41, 0x3F, 0x01}, // J + {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41}, // K + {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40}, // L + {0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F}, // M + {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F}, // N + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E}, // O + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x06}, // P + {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q + {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46}, // R + {0x00, 0x46, 0x49, 0x49, 0x49, 0x31}, // S + {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01}, // T + {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F}, // U + {0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F}, // V + {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F}, // W + {0x00, 0x63, 0x14, 0x08, 0x14, 0x63}, // X + {0x00, 0x07, 0x08, 0x70, 0x08, 0x07}, // Y + {0x00, 0x61, 0x51, 0x49, 0x45, 0x43}, // Z + {0x00, 0x00, 0x7F, 0x41, 0x41, 0x00}, // [ + {0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55}, // 55 + {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ] + {0x00, 0x04, 0x02, 0x01, 0x02, 0x04}, // ^ + {0x00, 0x40, 0x40, 0x40, 0x40, 0x40}, // _ + {0x00, 0x00, 0x01, 0x02, 0x04, 0x00}, // ' + {0x00, 0x20, 0x54, 0x54, 0x54, 0x78}, // a + {0x00, 0x7F, 0x48, 0x44, 0x44, 0x38}, // b + {0x00, 0x38, 0x44, 0x44, 0x44, 0x20}, // c + {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F}, // d + {0x00, 0x38, 0x54, 0x54, 0x54, 0x18}, // e + {0x00, 0x08, 0x7E, 0x09, 0x01, 0x02}, // f + {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C}, // g + {0x00, 0x7F, 0x08, 0x04, 0x04, 0x78}, // h + {0x00, 0x00, 0x44, 0x7D, 0x40, 0x00}, // i + {0x00, 0x40, 0x80, 0x84, 0x7D, 0x00}, // j + {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // k + {0x00, 0x00, 0x41, 0x7F, 0x40, 0x00}, // l + {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78}, // m + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x78}, // n + {0x00, 0x38, 0x44, 0x44, 0x44, 0x38}, // o + {0x00, 0xFC, 0x24, 0x24, 0x24, 0x18}, // p + {0x00, 0x18, 0x24, 0x24, 0x18, 0xFC}, // q + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x08}, // r + {0x00, 0x48, 0x54, 0x54, 0x54, 0x20}, // s + {0x00, 0x04, 0x3F, 0x44, 0x40, 0x20}, // t + {0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C}, // u + {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C}, // v + {0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C}, // w + {0x00, 0x44, 0x28, 0x10, 0x28, 0x44}, // x + {0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C}, // y + {0x00, 0x44, 0x64, 0x54, 0x4C, 0x44}, // z + {0x14, 0x14, 0x14, 0x14, 0x14, 0x14}, // horiz lines +}; + +/****************************************8*16的点阵************************************/ +const unsigned char g_f8X16[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, // ! 1 + 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " 2 + 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // # 3 + 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, // $ 4 + 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, // % 5 + 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, // & 6 + 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ' 7 + 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, // ( 8 + 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, // ) 9 + 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, // * 10 + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, // + 11 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // , 12 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // - 13 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // . 14 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, // / 15 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 16 + 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 17 + 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 18 + 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 19 + 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 20 + 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 21 + 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 22 + 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 23 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 24 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 25 + 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, // : 26 + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, // ;号 27 + 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, // < 28 + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, // = 29 + 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // > 30 + 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, // ? 31 + 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, // @ 32 + 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 33 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 34 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 35 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 36 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 37 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 38 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 39 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 40 + 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 41 + 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 42 + 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 43 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 44 + 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 45 + 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 46 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 47 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 48 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 49 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 50 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 51 + 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 52 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 53 + 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 54 + 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 55 + 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 56 + 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 57 + 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 58 + 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, // [ 59 + 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, // \ 60 + 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, // ] 61 + 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^ 62 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // _ 63 + 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ` 64 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 65 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 66 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 67 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 68 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 69 + 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 70 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 71 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 72 + 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 73 + 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 74 + 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 75 + 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 76 + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 77 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 78 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 79 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 80 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 81 + 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 82 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 83 + 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 84 + 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 85 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 86 + 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 87 + 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 88 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 89 + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 90 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, // { 91 + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // | 92 + 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, // } 93 + 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ~ 94 +}; + +static const unsigned short Font7x10[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ! + 0x2800, 0x2800, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x2400, 0x2400, 0x7C00, 0x2400, 0x4800, 0x7C00, 0x4800, 0x4800, 0x0000, 0x0000, // # + 0x3800, 0x5400, 0x5000, 0x3800, 0x1400, 0x5400, 0x5400, 0x3800, 0x1000, 0x0000, // $ + 0x2000, 0x5400, 0x5800, 0x3000, 0x2800, 0x5400, 0x1400, 0x0800, 0x0000, 0x0000, // % + 0x1000, 0x2800, 0x2800, 0x1000, 0x3400, 0x4800, 0x4800, 0x3400, 0x0000, 0x0000, // & + 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x0800, 0x1000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x1000, 0x0800, // ( + 0x2000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x1000, 0x2000, // ) + 0x1000, 0x3800, 0x1000, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * + 0x0000, 0x0000, 0x1000, 0x1000, 0x7C00, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // , + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3800, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // . + 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x0000, 0x0000, // / + 0x3800, 0x4400, 0x4400, 0x5400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 0 + 0x1000, 0x3000, 0x5000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // 1 + 0x3800, 0x4400, 0x4400, 0x0400, 0x0800, 0x1000, 0x2000, 0x7C00, 0x0000, 0x0000, // 2 + 0x3800, 0x4400, 0x0400, 0x1800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 3 + 0x0800, 0x1800, 0x2800, 0x2800, 0x4800, 0x7C00, 0x0800, 0x0800, 0x0000, 0x0000, // 4 + 0x7C00, 0x4000, 0x4000, 0x7800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 5 + 0x3800, 0x4400, 0x4000, 0x7800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 6 + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, // 7 + 0x3800, 0x4400, 0x4400, 0x3800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 8 + 0x3800, 0x4400, 0x4400, 0x4400, 0x3C00, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 9 + 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ; + 0x0000, 0x0000, 0x0C00, 0x3000, 0x4000, 0x3000, 0x0C00, 0x0000, 0x0000, 0x0000, // < + 0x0000, 0x0000, 0x0000, 0x7C00, 0x0000, 0x7C00, 0x0000, 0x0000, 0x0000, 0x0000, // = + 0x0000, 0x0000, 0x6000, 0x1800, 0x0400, 0x1800, 0x6000, 0x0000, 0x0000, 0x0000, // > + 0x3800, 0x4400, 0x0400, 0x0800, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ? + 0x3800, 0x4400, 0x4C00, 0x5400, 0x5C00, 0x4000, 0x4000, 0x3800, 0x0000, 0x0000, // @ + 0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000, // A + 0x7800, 0x4400, 0x4400, 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x0000, 0x0000, // B + 0x3800, 0x4400, 0x4000, 0x4000, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // C + 0x7000, 0x4800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4800, 0x7000, 0x0000, 0x0000, // D + 0x7C00, 0x4000, 0x4000, 0x7C00, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // E + 0x7C00, 0x4000, 0x4000, 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // F + 0x3800, 0x4400, 0x4000, 0x4000, 0x5C00, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // G + 0x4400, 0x4400, 0x4400, 0x7C00, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // H + 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3800, 0x0000, 0x0000, // I + 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // J + 0x4400, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // K + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // L + 0x4400, 0x6C00, 0x6C00, 0x5400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // M + 0x4400, 0x6400, 0x6400, 0x5400, 0x5400, 0x4C00, 0x4C00, 0x4400, 0x0000, 0x0000, // N + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // O + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // P + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x5400, 0x3800, 0x0400, 0x0000, // Q + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // R + 0x3800, 0x4400, 0x4000, 0x3000, 0x0800, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // S + 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // T + 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // U + 0x4400, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x1000, 0x0000, 0x0000, // V + 0x4400, 0x4400, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // W + 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, // X + 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // Y + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // Z + 0x1800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1800, // [ + 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0000, 0x0000, /* \ */ + 0x3000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3000, // ] + 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE00, // _ + 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x3800, 0x4400, 0x3C00, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // a + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x0000, 0x0000, // b + 0x0000, 0x0000, 0x3800, 0x4400, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // c + 0x0400, 0x0400, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // d + 0x0000, 0x0000, 0x3800, 0x4400, 0x7C00, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // e + 0x0C00, 0x1000, 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // f + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x7800, // g + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // h + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // i + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xE000, // j + 0x4000, 0x4000, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4400, 0x0000, 0x0000, // k + 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // l + 0x0000, 0x0000, 0x7800, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x0000, 0x0000, // m + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // n + 0x0000, 0x0000, 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // o + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x4000, 0x4000, // p + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x0400, // q + 0x0000, 0x0000, 0x5800, 0x6400, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // r + 0x0000, 0x0000, 0x3800, 0x4400, 0x3000, 0x0800, 0x4400, 0x3800, 0x0000, 0x0000, // s + 0x2000, 0x2000, 0x7800, 0x2000, 0x2000, 0x2000, 0x2000, 0x1800, 0x0000, 0x0000, // t + 0x0000, 0x0000, 0x4400, 0x4400, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // u + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x0000, 0x0000, // v + 0x0000, 0x0000, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // w + 0x0000, 0x0000, 0x4400, 0x2800, 0x1000, 0x1000, 0x2800, 0x4400, 0x0000, 0x0000, // x + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x6000, // y + 0x0000, 0x0000, 0x7C00, 0x0800, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // z + 0x1800, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1800, // { + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, // | + 0x3000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x3000, // } + 0x0000, 0x0000, 0x0000, 0x7400, 0x4C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +static const unsigned short Font11x18[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // ! + 0x0000, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x0000, 0x1980, 0x1980, 0x1980, 0x1980, 0x7FC0, 0x7FC0, 0x1980, 0x3300, + 0x7FC0, 0x7FC0, 0x3300, 0x3300, 0x3300, 0x3300, 0x0000, 0x0000, 0x0000, // # + 0x0000, 0x1E00, 0x3F00, 0x7580, 0x6580, 0x7400, 0x3C00, 0x1E00, 0x0700, + 0x0580, 0x6580, 0x6580, 0x7580, 0x3F00, 0x1E00, 0x0400, 0x0400, 0x0000, // $ + 0x0000, 0x7000, 0xD800, 0xD840, 0xD8C0, 0xD980, 0x7300, 0x0600, 0x0C00, + 0x1B80, 0x36C0, 0x66C0, 0x46C0, 0x06C0, 0x0380, 0x0000, 0x0000, 0x0000, // % + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x3300, 0x3300, 0x1E00, 0x0C00, 0x3CC0, + 0x66C0, 0x6380, 0x6180, 0x6380, 0x3EC0, 0x1C80, 0x0000, 0x0000, 0x0000, // & + 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x0080, 0x0100, 0x0300, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0300, 0x0100, 0x0080, // ( + 0x2000, 0x1000, 0x1800, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x1800, 0x1000, 0x2000, // ) + 0x0000, 0x0C00, 0x2D00, 0x3F00, 0x1E00, 0x3300, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * + 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0xFFC0, 0xFFC0, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800, // , + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // . + 0x0000, 0x0300, 0x0300, 0x0300, 0x0600, 0x0600, 0x0600, 0x0600, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000, // / + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6D80, 0x6D80, + 0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 0 + 0x0000, 0x0600, 0x0E00, 0x1E00, 0x3600, 0x2600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // 1 + 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, 0x6180, 0x0180, 0x0300, 0x0600, + 0x0C00, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // 2 + 0x0000, 0x1C00, 0x3E00, 0x6300, 0x6300, 0x0300, 0x0E00, 0x0E00, 0x0300, + 0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 3 + 0x0000, 0x0600, 0x0E00, 0x0E00, 0x1E00, 0x1E00, 0x1600, 0x3600, 0x3600, + 0x6600, 0x7F80, 0x7F80, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // 4 + 0x0000, 0x7F00, 0x7F00, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x6380, + 0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 5 + 0x0000, 0x1E00, 0x3F00, 0x3380, 0x6180, 0x6000, 0x6E00, 0x7F00, 0x7380, + 0x6180, 0x6180, 0x6180, 0x3380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 6 + 0x0000, 0x7F80, 0x7F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0600, 0x0C00, + 0x0C00, 0x0C00, 0x0800, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000, // 7 + 0x0000, 0x1E00, 0x3F00, 0x6380, 0x6180, 0x6180, 0x2100, 0x1E00, 0x3F00, + 0x6180, 0x6180, 0x6180, 0x6180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 8 + 0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, + 0x1D80, 0x0180, 0x6180, 0x7300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 9 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800, // ; + 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0380, 0x0E00, 0x3800, 0x6000, + 0x3800, 0x0E00, 0x0380, 0x0080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // < + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7F80, 0x7F80, 0x0000, 0x0000, + 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // = + 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x7000, 0x1C00, 0x0700, 0x0180, + 0x0700, 0x1C00, 0x7000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // > + 0x0000, 0x1F00, 0x3F80, 0x71C0, 0x60C0, 0x00C0, 0x01C0, 0x0380, 0x0700, + 0x0E00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // ? + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x7180, 0x6380, 0x6F80, 0x6D80, 0x6D80, + 0x6F80, 0x6780, 0x6000, 0x3200, 0x3E00, 0x1C00, 0x0000, 0x0000, 0x0000, // @ + 0x0000, 0x0E00, 0x0E00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x3180, 0x3180, + 0x3F80, 0x3F80, 0x3180, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000, // A + 0x0000, 0x7C00, 0x7E00, 0x6300, 0x6300, 0x6300, 0x6300, 0x7E00, 0x7E00, + 0x6300, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, 0x0000, 0x0000, 0x0000, // B + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6000, + 0x6000, 0x6000, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // C + 0x0000, 0x7C00, 0x7F00, 0x6300, 0x6380, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6300, 0x6300, 0x7E00, 0x7C00, 0x0000, 0x0000, 0x0000, // D + 0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, + 0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // E + 0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, + 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, // F + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6380, + 0x6380, 0x6180, 0x6180, 0x3180, 0x3F80, 0x1E00, 0x0000, 0x0000, 0x0000, // G + 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x7F80, 0x7F80, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // H + 0x0000, 0x3F00, 0x3F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3F00, 0x3F00, 0x0000, 0x0000, 0x0000, // I + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // J + 0x0000, 0x60C0, 0x6180, 0x6300, 0x6600, 0x6600, 0x6C00, 0x7800, 0x7C00, + 0x6600, 0x6600, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // K + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, + 0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // L + 0x0000, 0x71C0, 0x71C0, 0x7BC0, 0x7AC0, 0x6AC0, 0x6AC0, 0x6EC0, 0x64C0, + 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000, // M + 0x0000, 0x7180, 0x7180, 0x7980, 0x7980, 0x7980, 0x6D80, 0x6D80, 0x6D80, + 0x6580, 0x6780, 0x6780, 0x6780, 0x6380, 0x6380, 0x0000, 0x0000, 0x0000, // N + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // O + 0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6180, 0x6380, 0x7F00, + 0x7E00, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, // P + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6580, 0x6780, 0x3300, 0x3F80, 0x1E40, 0x0000, 0x0000, 0x0000, // Q + 0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, + 0x6600, 0x6300, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // R + 0x0000, 0x0E00, 0x1F00, 0x3180, 0x3180, 0x3000, 0x3800, 0x1E00, 0x0700, + 0x0380, 0x6180, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // S + 0x0000, 0xFFC0, 0xFFC0, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // T + 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // U + 0x0000, 0x60C0, 0x60C0, 0x60C0, 0x3180, 0x3180, 0x3180, 0x1B00, 0x1B00, + 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x0400, 0x0000, 0x0000, 0x0000, // V + 0x0000, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xCCC0, 0x4C80, 0x4C80, + 0x5E80, 0x5280, 0x5280, 0x7380, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // W + 0x0000, 0xC0C0, 0x6080, 0x6180, 0x3300, 0x3B00, 0x1E00, 0x0C00, 0x0C00, + 0x1E00, 0x1F00, 0x3B00, 0x7180, 0x6180, 0xC0C0, 0x0000, 0x0000, 0x0000, // X + 0x0000, 0xC0C0, 0x6180, 0x6180, 0x3300, 0x3300, 0x1E00, 0x1E00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // Y + 0x0000, 0x3F80, 0x3F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0C00, 0x0C00, + 0x1800, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // Z + 0x0F00, 0x0F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0F00, 0x0F00, // [ + 0x0000, 0x1800, 0x1800, 0x1800, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0300, 0x0300, 0x0300, 0x0000, 0x0000, 0x0000, /* \ */ + 0x1E00, 0x1E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x1E00, 0x1E00, // ] + 0x0000, 0x0C00, 0x0C00, 0x1E00, 0x1200, 0x3300, 0x3300, 0x6180, 0x6180, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFE0, 0x0000, // _ + 0x0000, 0x3800, 0x1800, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F00, 0x3F80, 0x6180, 0x0180, + 0x1F80, 0x3F80, 0x6180, 0x6380, 0x7F80, 0x38C0, 0x0000, 0x0000, 0x0000, // a + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x0000, 0x0000, 0x0000, // b + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, + 0x6000, 0x6000, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // c + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x1D80, 0x3F80, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0000, 0x0000, 0x0000, // d + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, + 0x7F80, 0x7F80, 0x6000, 0x7180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // e + 0x0000, 0x07C0, 0x0FC0, 0x0C00, 0x0C00, 0x7F80, 0x7F80, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // f + 0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x6380, 0x7F00, 0x3E00, // g + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6F00, 0x7F80, 0x7180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // h + 0x0000, 0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // i + 0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x4600, 0x7E00, 0x3C00, // j + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6180, 0x6300, 0x6600, 0x6C00, + 0x7C00, 0x7600, 0x6300, 0x6300, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // k + 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // l + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xFFC0, 0xCEC0, 0xCCC0, + 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0x0000, 0x0000, 0x0000, // m + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6F00, 0x7F80, 0x7180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // n + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // o + 0x0000, 0x0000, 0x0000, 0x0000, 0x6E00, 0x7F00, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x6000, 0x6000, 0x6000, 0x6000, // p + 0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x0180, 0x0180, 0x0180, // q + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6700, 0x3F80, 0x3900, 0x3000, + 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x0000, 0x0000, 0x0000, // r + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F80, 0x6180, 0x6000, + 0x7F00, 0x3F80, 0x0180, 0x6180, 0x7F00, 0x1E00, 0x0000, 0x0000, 0x0000, // s + 0x0000, 0x0000, 0x0800, 0x1800, 0x1800, 0x7F00, 0x7F00, 0x1800, 0x1800, + 0x1800, 0x1800, 0x1800, 0x1800, 0x1F80, 0x0F80, 0x0000, 0x0000, 0x0000, // t + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6380, 0x7F80, 0x3D80, 0x0000, 0x0000, 0x0000, // u + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x60C0, 0x3180, 0x3180, 0x3180, + 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0600, 0x0000, 0x0000, 0x0000, // v + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xDD80, 0xDD80, 0x5500, + 0x5500, 0x5500, 0x7700, 0x7700, 0x2200, 0x2200, 0x0000, 0x0000, 0x0000, // w + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x3300, 0x3300, 0x1E00, + 0x0C00, 0x0C00, 0x1E00, 0x3300, 0x3300, 0x6180, 0x0000, 0x0000, 0x0000, // x + 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x3180, 0x3300, 0x3300, + 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x1C00, 0x7C00, 0x7000, // y + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FC0, 0x7FC0, 0x0180, 0x0300, + 0x0600, 0x0C00, 0x1800, 0x3000, 0x7FC0, 0x7FC0, 0x0000, 0x0000, 0x0000, // z + 0x0380, 0x0780, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0E00, 0x1C00, + 0x1C00, 0x0E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0780, 0x0380, // { + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, // | + 0x3800, 0x3C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0E00, 0x0700, + 0x0700, 0x0E00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3C00, 0x3800, // } + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3880, 0x7F80, + 0x4700, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; +static const unsigned short Font16x26[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [ ] + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, + 0x01C0, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [!] + 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ["] + 0x01CE, 0x03CE, 0x03DE, 0x039E, 0x039C, 0x079C, 0x3FFF, 0x7FFF, 0x0738, 0x0F38, 0x0F78, 0x0F78, 0x0E78, 0xFFFF, + 0xFFFF, 0x1EF0, 0x1CF0, 0x1CE0, 0x3CE0, 0x3DE0, 0x39E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [#] + 0x03FC, 0x0FFE, 0x1FEE, 0x1EE0, 0x1EE0, 0x1EE0, 0x1EE0, 0x1FE0, 0x0FE0, 0x07E0, 0x03F0, 0x01FC, 0x01FE, 0x01FE, + 0x01FE, 0x01FE, 0x01FE, 0x01FE, 0x3DFE, 0x3FFC, 0x0FF0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, // Ascii = [$] + 0x3E03, 0xF707, 0xE78F, 0xE78E, 0xE39E, 0xE3BC, 0xE7B8, 0xE7F8, 0xF7F0, 0x3FE0, 0x01C0, 0x03FF, 0x07FF, 0x07F3, + 0x0FF3, 0x1EF3, 0x3CF3, 0x38F3, 0x78F3, 0xF07F, 0xE03F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [%] + 0x07E0, 0x0FF8, 0x0F78, 0x1F78, 0x1F78, 0x1F78, 0x0F78, 0x0FF0, 0x0FE0, 0x1F80, 0x7FC3, 0xFBC3, 0xF3E7, 0xF1F7, + 0xF0F7, 0xF0FF, 0xF07F, 0xF83E, 0x7C7F, 0x3FFF, 0x1FEF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [&] + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ['] + 0x003F, 0x007C, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x0780, 0x0780, 0x0F80, 0x0F00, 0x0F00, 0x0F00, 0x0F00, 0x0F00, + 0x0F00, 0x0F80, 0x0780, 0x0780, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x007C, 0x003F, 0x000F, 0x0000, // Ascii = [(] + 0x7E00, 0x1F00, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x00F0, 0x00F0, 0x00F8, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, + 0x0078, 0x00F8, 0x00F0, 0x00F0, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x1F00, 0x7E00, 0x7800, 0x0000, // Ascii = [)] + 0x03E0, 0x03C0, 0x01C0, 0x39CE, 0x3FFF, 0x3F7F, 0x0320, 0x0370, 0x07F8, 0x0F78, 0x1F3C, 0x0638, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [*] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0xFFFF, + 0xFFFF, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [+] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x0380, // Ascii = [,] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFE, 0x3FFE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [-] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [.] + 0x000F, 0x000F, 0x001E, 0x001E, 0x003C, 0x003C, 0x0078, 0x0078, 0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, + 0x0780, 0x0780, 0x0F00, 0x0F00, 0x1E00, 0x1E00, 0x3C00, 0x3C00, 0x7800, 0x7800, 0xF000, 0x0000, // Ascii = [/] + 0x07F0, 0x0FF8, 0x1F7C, 0x3E3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, + 0x7C1F, 0x7C1F, 0x3C1E, 0x3E3E, 0x1F7C, 0x0FF8, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [0] + 0x00F0, 0x07F0, 0x3FF0, 0x3FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, + 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [1] + 0x0FE0, 0x3FF8, 0x3C7C, 0x003C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x007C, 0x00F8, 0x01F0, 0x03E0, 0x07C0, + 0x0780, 0x0F00, 0x1E00, 0x3E00, 0x3C00, 0x3FFE, 0x3FFE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [2] + 0x0FF0, 0x1FF8, 0x1C7C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x00F8, 0x0FF0, 0x0FF8, 0x007C, 0x003E, 0x001E, + 0x001E, 0x001E, 0x001E, 0x003E, 0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [3] + 0x0078, 0x00F8, 0x00F8, 0x01F8, 0x03F8, 0x07F8, 0x07F8, 0x0F78, 0x1E78, 0x1E78, 0x3C78, 0x7878, 0x7878, 0xFFFF, + 0xFFFF, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [4] + 0x1FFC, 0x1FFC, 0x1FFC, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FE0, 0x1FF8, 0x00FC, 0x007C, 0x003E, 0x003E, + 0x001E, 0x003E, 0x003E, 0x003C, 0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [5] + 0x01FC, 0x07FE, 0x0F8E, 0x1F00, 0x1E00, 0x3E00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFC, 0x7F3E, 0x7E1F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3E0F, 0x1E1F, 0x1F3E, 0x0FFC, 0x03F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [6] + 0x3FFF, 0x3FFF, 0x3FFF, 0x000F, 0x001E, 0x001E, 0x003C, 0x0038, 0x0078, 0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, + 0x03C0, 0x0780, 0x0F80, 0x0F80, 0x0F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [7] + 0x07F8, 0x0FFC, 0x1F3E, 0x1E1E, 0x3E1E, 0x3E1E, 0x1E1E, 0x1F3C, 0x0FF8, 0x07F0, 0x0FF8, 0x1EFC, 0x3E3E, 0x3C1F, + 0x7C1F, 0x7C0F, 0x7C0F, 0x3C1F, 0x3F3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [8] + 0x07F0, 0x0FF8, 0x1E7C, 0x3C3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x3C1F, 0x3E3F, 0x1FFF, 0x07EF, 0x001F, + 0x001E, 0x001E, 0x003E, 0x003C, 0x38F8, 0x3FF0, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [9] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [:] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x0380, // Ascii = [;] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x000F, 0x003F, 0x00FC, 0x03F0, 0x0FC0, 0x3F00, 0xFE00, + 0x3F00, 0x0FC0, 0x03F0, 0x00FC, 0x003F, 0x000F, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [<] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [=] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE000, 0xF800, 0x7E00, 0x1F80, 0x07E0, 0x01F8, 0x007E, 0x001F, + 0x007E, 0x01F8, 0x07E0, 0x1F80, 0x7E00, 0xF800, 0xE000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [>] + 0x1FF0, 0x3FFC, 0x383E, 0x381F, 0x381F, 0x001E, 0x001E, 0x003C, 0x0078, 0x00F0, 0x01E0, 0x03C0, 0x03C0, 0x07C0, + 0x07C0, 0x0000, 0x0000, 0x0000, 0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [?] + 0x03F8, 0x0FFE, 0x1F1E, 0x3E0F, 0x3C7F, 0x78FF, 0x79EF, 0x73C7, 0xF3C7, 0xF38F, 0xF38F, 0xF38F, 0xF39F, 0xF39F, + 0x73FF, 0x7BFF, 0x79F7, 0x3C00, 0x1F1C, 0x0FFC, 0x03F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [@] + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x07F0, 0x0F78, 0x0F78, 0x0E7C, 0x1E3C, 0x1E3C, 0x3C3E, + 0x3FFE, 0x3FFF, 0x781F, 0x780F, 0xF00F, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [A] + 0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FFC, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7C, 0x3FF0, 0x3FF8, 0x3C7E, + 0x3C1F, 0x3C1F, 0x3C0F, 0x3C0F, 0x3C1F, 0x3FFE, 0x3FF8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [B] + 0x0000, 0x0000, 0x0000, 0x01FF, 0x07FF, 0x1F87, 0x3E00, 0x3C00, 0x7C00, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, + 0x7C00, 0x7C00, 0x3E00, 0x3F00, 0x1F83, 0x07FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [C] + 0x0000, 0x0000, 0x0000, 0x7FF0, 0x7FFC, 0x787E, 0x781F, 0x781F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, + 0x780F, 0x780F, 0x781F, 0x781E, 0x787E, 0x7FF8, 0x7FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [D] + 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFE, 0x3FFE, 0x3E00, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [E] + 0x0000, 0x0000, 0x0000, 0x1FFF, 0x1FFF, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FFF, 0x1FFF, 0x1E00, + 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [F] + 0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x7C00, 0x7C00, 0x7800, 0xF800, 0xF800, 0xF87F, 0xF87F, + 0x780F, 0x7C0F, 0x7C0F, 0x3E0F, 0x1F8F, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [G] + 0x0000, 0x0000, 0x0000, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7FFF, 0x7FFF, 0x7C1F, + 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [H] + 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [I] + 0x0000, 0x0000, 0x0000, 0x1FFC, 0x1FFC, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, + 0x007C, 0x007C, 0x0078, 0x0078, 0x38F8, 0x3FF0, 0x3FC0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [J] + 0x0000, 0x0000, 0x0000, 0x3C1F, 0x3C1E, 0x3C3C, 0x3C78, 0x3CF0, 0x3DE0, 0x3FE0, 0x3FC0, 0x3F80, 0x3FC0, 0x3FE0, + 0x3DF0, 0x3CF0, 0x3C78, 0x3C7C, 0x3C3E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [K] + 0x0000, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [L] + 0x0000, 0x0000, 0x0000, 0xF81F, 0xFC1F, 0xFC1F, 0xFE3F, 0xFE3F, 0xFE3F, 0xFF7F, 0xFF77, 0xFF77, 0xF7F7, 0xF7E7, + 0xF3E7, 0xF3E7, 0xF3C7, 0xF007, 0xF007, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [M] + 0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7E0F, 0x7F0F, 0x7F0F, 0x7F8F, 0x7F8F, 0x7FCF, 0x7BEF, 0x79EF, 0x79FF, + 0x78FF, 0x78FF, 0x787F, 0x783F, 0x783F, 0x781F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [N] + 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, + 0xF80F, 0x780F, 0x780F, 0x7C1F, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [O] + 0x0000, 0x0000, 0x0000, 0x3FFC, 0x3FFF, 0x3E1F, 0x3E0F, 0x3E0F, 0x3E0F, 0x3E0F, 0x3E1F, 0x3E3F, 0x3FFC, 0x3FF0, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [P] + 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, + 0xF80F, 0x780F, 0x780F, 0x7C1F, 0x3E3E, 0x1FFC, 0x07F8, 0x007C, 0x003F, 0x000F, 0x0003, 0x0000, // Ascii = [Q] + 0x0000, 0x0000, 0x0000, 0x3FF0, 0x3FFC, 0x3C7E, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C3C, 0x3CFC, 0x3FF0, 0x3FE0, + 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, 0x3C1E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [R] + 0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x3E0E, 0x3C00, 0x3C00, 0x3C00, 0x3E00, 0x1FC0, 0x0FF8, 0x03FE, 0x007F, + 0x001F, 0x000F, 0x000F, 0x201F, 0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [S] + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [T] + 0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, + 0x7C0F, 0x7C0F, 0x3C1E, 0x3C1E, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [U] + 0x0000, 0x0000, 0x0000, 0xF007, 0xF007, 0xF807, 0x780F, 0x7C0F, 0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1F3C, 0x1F78, + 0x0F78, 0x0FF8, 0x07F0, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [V] + 0x0000, 0x0000, 0x0000, 0xE003, 0xF003, 0xF003, 0xF007, 0xF3E7, 0xF3E7, 0xF3E7, 0x73E7, 0x7BF7, 0x7FF7, 0x7FFF, + 0x7F7F, 0x7F7F, 0x7F7E, 0x3F7E, 0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [W] + 0x0000, 0x0000, 0x0000, 0xF807, 0x7C0F, 0x3E1E, 0x3E3E, 0x1F3C, 0x0FF8, 0x07F0, 0x07E0, 0x03E0, 0x03E0, 0x07F0, + 0x0FF8, 0x0F7C, 0x1E7C, 0x3C3E, 0x781F, 0x780F, 0xF00F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [X] + 0x0000, 0x0000, 0x0000, 0xF807, 0x7807, 0x7C0F, 0x3C1E, 0x3E1E, 0x1F3C, 0x0F78, 0x0FF8, 0x07F0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Y] + 0x0000, 0x0000, 0x0000, 0x7FFF, 0x7FFF, 0x000F, 0x001F, 0x003E, 0x007C, 0x00F8, 0x00F0, 0x01E0, 0x03E0, 0x07C0, + 0x0F80, 0x0F00, 0x1E00, 0x3E00, 0x7C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Z] + 0x07FF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, + 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x07FF, 0x07FF, 0x0000, // Ascii = [[] + 0x7800, 0x7800, 0x3C00, 0x3C00, 0x1E00, 0x1E00, 0x0F00, 0x0F00, 0x0780, 0x0780, 0x03C0, 0x03C0, 0x01E0, 0x01E0, + 0x00F0, 0x00F0, 0x0078, 0x0078, 0x003C, 0x003C, 0x001E, 0x001E, 0x000F, 0x000F, 0x0007, 0x0000, // Ascii = [\] + 0x7FF0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, + 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x7FF0, 0x7FF0, 0x0000, // Ascii = []] + 0x00C0, 0x01C0, 0x01C0, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x0778, 0x0F78, 0x0F38, 0x1E3C, 0x1E3C, 0x3C1E, 0x3C1E, + 0x380F, 0x780F, 0x7807, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [^] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, // Ascii = [_] + 0x00F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [`] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0FF8, 0x3FFC, 0x3C7C, 0x003E, 0x003E, 0x003E, 0x07FE, 0x1FFE, + 0x3E3E, 0x7C3E, 0x783E, 0x7C3E, 0x7C7E, 0x3FFF, 0x1FCF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [a] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFE, 0x3F3E, 0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3C1F, 0x3C1E, 0x3F3E, 0x3FFC, 0x3BF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [b] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x3E00, 0x3C00, 0x7C00, 0x7C00, + 0x7C00, 0x3C00, 0x3E00, 0x3E00, 0x1F87, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [c] + 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x07FF, 0x1FFF, 0x3E3F, 0x3C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x781F, + 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, 0x3E7F, 0x1FFF, 0x0FDF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [d] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03F8, 0x0FFC, 0x1F3E, 0x3E1E, 0x3C1F, 0x7C1F, 0x7FFF, 0x7FFF, + 0x7C00, 0x7C00, 0x3C00, 0x3E00, 0x1F07, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [e] + 0x01FF, 0x03E1, 0x03C0, 0x07C0, 0x07C0, 0x07C0, 0x7FFF, 0x7FFF, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, + 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [f] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EF, 0x1FFF, 0x3E7F, 0x3C1F, 0x7C1F, 0x7C1F, 0x781F, 0x781F, + 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, 0x3E7F, 0x1FFF, 0x0FDF, 0x001E, 0x001E, 0x001E, 0x387C, 0x3FF8, // Ascii = [g] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DFC, 0x3FFE, 0x3F9E, 0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, + 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [h] + 0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FE0, 0x7FE0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, + 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [i] + 0x00F8, 0x00F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FF8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, + 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F0, 0x71F0, 0x7FE0, // Ascii = [j] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C1F, 0x3C3E, 0x3C7C, 0x3CF8, 0x3DF0, 0x3DE0, 0x3FC0, 0x3FC0, + 0x3FE0, 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [k] + 0x7FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, + 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [l] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF79E, 0xFFFF, 0xFFFF, 0xFFFF, 0xFBE7, 0xF9E7, 0xF1C7, 0xF1C7, + 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [m] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DFC, 0x3FFE, 0x3F9E, 0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, + 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [n] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x3C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, + 0x780F, 0x780F, 0x7C1F, 0x3C1F, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [o] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DF8, 0x3FFE, 0x3F3E, 0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3C1F, 0x3E1E, 0x3F3E, 0x3FFC, 0x3FF8, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, // Ascii = [p] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EE, 0x1FFE, 0x3E7E, 0x3C1E, 0x7C1E, 0x781E, 0x781E, 0x781E, + 0x781E, 0x781E, 0x7C1E, 0x7C3E, 0x3E7E, 0x1FFE, 0x0FDE, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, // Ascii = [q] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F7F, 0x1FFF, 0x1FE7, 0x1FC7, 0x1F87, 0x1F00, 0x1F00, 0x1F00, + 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [r] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x1E0E, 0x3E00, 0x3E00, 0x3F00, 0x1FE0, 0x07FC, + 0x00FE, 0x003E, 0x001E, 0x001E, 0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [s] + 0x0000, 0x0000, 0x0000, 0x0780, 0x0780, 0x0780, 0x7FFF, 0x7FFF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, + 0x0780, 0x0780, 0x0780, 0x0780, 0x07C0, 0x03FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [t] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, + 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7E, 0x3EFE, 0x1FFE, 0x0FDE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [u] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF007, 0x780F, 0x780F, 0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1E3C, + 0x0F78, 0x0F78, 0x0FF0, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [v] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF003, 0xF1E3, 0xF3E3, 0xF3E7, 0xF3F7, 0xF3F7, 0x7FF7, 0x7F77, + 0x7F7F, 0x7F7F, 0x7F7F, 0x3E3E, 0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [w] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7C0F, 0x3E1E, 0x3E3C, 0x1F3C, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, + 0x07F0, 0x07F8, 0x0FF8, 0x1E7C, 0x3E3E, 0x3C1F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [x] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF807, 0x780F, 0x7C0F, 0x3C1E, 0x3C1E, 0x1E3C, 0x1E3C, 0x1F3C, + 0x0F78, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x0780, 0x0F80, 0x7F00, // Ascii = [y] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x001F, 0x003E, 0x007C, 0x00F8, 0x01F0, 0x03E0, + 0x07C0, 0x0F80, 0x1F00, 0x1E00, 0x3C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [z] + 0x01FE, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x3F80, 0x3F80, 0x03C0, + 0x01C0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x03E0, 0x01FE, 0x007E, 0x0000, // Ascii = [{] + 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, + 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, // Ascii = [|] + 0x3FC0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x03C0, 0x01C0, 0x01E0, 0x00FE, 0x00FE, 0x01E0, + 0x01C0, 0x03C0, 0x03C0, 0x01C0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x03E0, 0x3FC0, 0x3F00, 0x0000, // Ascii = [}] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3F07, 0x7FC7, 0x73E7, + 0xF1FF, 0xF07E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [~] +}; +static const unsigned short Font6x8[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, 0x2000, 0x0000, // ! + 0x5000, 0x5000, 0x5000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x5000, 0x5000, 0xf800, 0x5000, 0xf800, 0x5000, 0x5000, 0x0000, // # + 0x2000, 0x7800, 0xa000, 0x7000, 0x2800, 0xf000, 0x2000, 0x0000, // $ + 0xc000, 0xc800, 0x1000, 0x2000, 0x4000, 0x9800, 0x1800, 0x0000, // % + 0x4000, 0xa000, 0xa000, 0x4000, 0xa800, 0x9000, 0x6800, 0x0000, // & + 0x3000, 0x3000, 0x2000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x1000, 0x2000, 0x4000, 0x4000, 0x4000, 0x2000, 0x1000, 0x0000, // ( + 0x4000, 0x2000, 0x1000, 0x1000, 0x1000, 0x2000, 0x4000, 0x0000, // ) + 0x2000, 0xa800, 0x7000, 0xf800, 0x7000, 0xa800, 0x2000, 0x0000, // * + 0x0000, 0x2000, 0x2000, 0xf800, 0x2000, 0x2000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3000, 0x2000, 0x0000, // , + 0x0000, 0x0000, 0x0000, 0xf800, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3000, 0x0000, // . + 0x0000, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x0000, 0x0000, // / + 0x7000, 0x8800, 0x9800, 0xa800, 0xc800, 0x8800, 0x7000, 0x0000, // 0 + 0x2000, 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // 1 + 0x7000, 0x8800, 0x0800, 0x7000, 0x8000, 0x8000, 0xf800, 0x0000, // 2 + 0xf800, 0x0800, 0x1000, 0x3000, 0x0800, 0x8800, 0x7000, 0x0000, // 3 + 0x1000, 0x3000, 0x5000, 0x9000, 0xf800, 0x1000, 0x1000, 0x0000, // 4 + 0xf800, 0x8000, 0xf000, 0x0800, 0x0800, 0x8800, 0x7000, 0x0000, // 5 + 0x3800, 0x4000, 0x8000, 0xf000, 0x8800, 0x8800, 0x7000, 0x0000, // 6 + 0xf800, 0x0800, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x0000, // 7 + 0x7000, 0x8800, 0x8800, 0x7000, 0x8800, 0x8800, 0x7000, 0x0000, // 8 + 0x7000, 0x8800, 0x8800, 0x7800, 0x0800, 0x1000, 0xe000, 0x0000, // 9 + 0x0000, 0x0000, 0x2000, 0x0000, 0x2000, 0x0000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x2000, 0x0000, 0x2000, 0x2000, 0x4000, 0x0000, // ; + 0x0800, 0x1000, 0x2000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0000, // < + 0x0000, 0x0000, 0xf800, 0x0000, 0xf800, 0x0000, 0x0000, 0x0000, // = + 0x4000, 0x2000, 0x1000, 0x0800, 0x1000, 0x2000, 0x4000, 0x0000, // > + 0x7000, 0x8800, 0x0800, 0x3000, 0x2000, 0x0000, 0x2000, 0x0000, // ? + 0x7000, 0x8800, 0xa800, 0xb800, 0xb000, 0x8000, 0x7800, 0x0000, // @ + 0x2000, 0x5000, 0x8800, 0x8800, 0xf800, 0x8800, 0x8800, 0x0000, // A + 0xf000, 0x8800, 0x8800, 0xf000, 0x8800, 0x8800, 0xf000, 0x0000, // B + 0x7000, 0x8800, 0x8000, 0x8000, 0x8000, 0x8800, 0x7000, 0x0000, // C + 0xf000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0xf000, 0x0000, // D + 0xf800, 0x8000, 0x8000, 0xf000, 0x8000, 0x8000, 0xf800, 0x0000, // E + 0xf800, 0x8000, 0x8000, 0xf000, 0x8000, 0x8000, 0x8000, 0x0000, // F + 0x7800, 0x8800, 0x8000, 0x8000, 0x9800, 0x8800, 0x7800, 0x0000, // G + 0x8800, 0x8800, 0x8800, 0xf800, 0x8800, 0x8800, 0x8800, 0x0000, // H + 0x7000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // I + 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x9000, 0x6000, 0x0000, // J + 0x8800, 0x9000, 0xa000, 0xc000, 0xa000, 0x9000, 0x8800, 0x0000, // K + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0xf800, 0x0000, // L + 0x8800, 0xd800, 0xa800, 0xa800, 0xa800, 0x8800, 0x8800, 0x0000, // M + 0x8800, 0x8800, 0xc800, 0xa800, 0x9800, 0x8800, 0x8800, 0x0000, // N + 0x7000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // O + 0xf000, 0x8800, 0x8800, 0xf000, 0x8000, 0x8000, 0x8000, 0x0000, // P + 0x7000, 0x8800, 0x8800, 0x8800, 0xa800, 0x9000, 0x6800, 0x0000, // Q + 0xf000, 0x8800, 0x8800, 0xf000, 0xa000, 0x9000, 0x8800, 0x0000, // R + 0x7000, 0x8800, 0x8000, 0x7000, 0x0800, 0x8800, 0x7000, 0x0000, // S + 0xf800, 0xa800, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, // T + 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // U + 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x5000, 0x2000, 0x0000, // V + 0x8800, 0x8800, 0x8800, 0xa800, 0xa800, 0xa800, 0x5000, 0x0000, // W + 0x8800, 0x8800, 0x5000, 0x2000, 0x5000, 0x8800, 0x8800, 0x0000, // X + 0x8800, 0x8800, 0x5000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, // Y + 0xf800, 0x0800, 0x1000, 0x7000, 0x4000, 0x8000, 0xf800, 0x0000, // Z + 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7800, 0x0000, // [ + 0x0000, 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0000, 0x0000, /* \ */ + 0x7800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x7800, 0x0000, // ] + 0x2000, 0x5000, 0x8800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf800, 0x0000, // _ + 0x6000, 0x6000, 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x6000, 0x1000, 0x7000, 0x9000, 0x7800, 0x0000, // a + 0x8000, 0x8000, 0xb000, 0xc800, 0x8800, 0xc800, 0xb000, 0x0000, // b + 0x0000, 0x0000, 0x7000, 0x8800, 0x8000, 0x8800, 0x7000, 0x0000, // c + 0x0800, 0x0800, 0x6800, 0x9800, 0x8800, 0x9800, 0x6800, 0x0000, // d + 0x0000, 0x0000, 0x7000, 0x8800, 0xf800, 0x8000, 0x7000, 0x0000, // e + 0x1000, 0x2800, 0x2000, 0x7000, 0x2000, 0x2000, 0x2000, 0x0000, // f + 0x0000, 0x0000, 0x7000, 0x9800, 0x9800, 0x6800, 0x0800, 0x0000, // g + 0x8000, 0x8000, 0xb000, 0xc800, 0x8800, 0x8800, 0x8800, 0x0000, // h + 0x2000, 0x0000, 0x6000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // i + 0x1000, 0x0000, 0x1000, 0x1000, 0x1000, 0x9000, 0x6000, 0x0000, // j + 0x8000, 0x8000, 0x9000, 0xa000, 0xc000, 0xa000, 0x9000, 0x0000, // k + 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // l + 0x0000, 0x0000, 0xd000, 0xa800, 0xa800, 0xa800, 0xa800, 0x0000, // m + 0x0000, 0x0000, 0xb000, 0xc800, 0x8800, 0x8800, 0x8800, 0x0000, // n + 0x0000, 0x0000, 0x7000, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // o + 0x0000, 0x0000, 0xb000, 0xc800, 0xc800, 0xb000, 0x8000, 0x0000, // p + 0x0000, 0x0000, 0x6800, 0x9800, 0x9800, 0x6800, 0x0800, 0x0000, // q + 0x0000, 0x0000, 0xb000, 0xc800, 0x8000, 0x8000, 0x8000, 0x0000, // r + 0x0000, 0x0000, 0x7800, 0x8000, 0x7000, 0x0800, 0xf000, 0x0000, // s + 0x2000, 0x2000, 0xf800, 0x2000, 0x2000, 0x2800, 0x1000, 0x0000, // t + 0x0000, 0x0000, 0x8800, 0x8800, 0x8800, 0x9800, 0x6800, 0x0000, // u + 0x0000, 0x0000, 0x8800, 0x8800, 0x8800, 0x5000, 0x2000, 0x0000, // v + 0x0000, 0x0000, 0x8800, 0x8800, 0xa800, 0xa800, 0x5000, 0x0000, // w + 0x0000, 0x0000, 0x8800, 0x5000, 0x2000, 0x5000, 0x8800, 0x0000, // x + 0x0000, 0x0000, 0x8800, 0x8800, 0x7800, 0x0800, 0x8800, 0x0000, // y + 0x0000, 0x0000, 0xf800, 0x1000, 0x2000, 0x4000, 0xf800, 0x0000, // z + 0x1000, 0x2000, 0x2000, 0x4000, 0x2000, 0x2000, 0x1000, 0x0000, // { + 0x2000, 0x2000, 0x2000, 0x0000, 0x2000, 0x2000, 0x2000, 0x0000, // | + 0x4000, 0x2000, 0x2000, 0x1000, 0x2000, 0x2000, 0x4000, 0x0000, // } + 0x4000, 0xa800, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +FontDef Font_7x10 = {7, 10, Font7x10}; +FontDef Font_6x8 = {6, 8, Font6x8}; +FontDef Font_11x18 = {11, 18, Font11x18}; +FontDef Font_16x26 = {16, 26, Font16x26}; \ No newline at end of file diff --git a/src/vendor/test/gyro/ssd1306_fonts.h b/src/vendor/test/gyro/ssd1306_fonts.h new file mode 100644 index 0000000000000000000000000000000000000000..21afb48aa124f6e4579b1520082c9d3571f381db --- /dev/null +++ b/src/vendor/test/gyro/ssd1306_fonts.h @@ -0,0 +1,58 @@ +/* + MIT License + + Copyright (c) 2018, Alexey Dynda + + 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. +*/ +/** + * @file ssd1306_fonts.h Fonts for monochrome/rgb oled display + */ + +#ifndef SSD1306_FONTS_H +#define SSD1306_FONTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup LCD_FONTS FONTS: Supported LCD fonts + * @{ + */ + +extern const unsigned char g_f6X8[][6]; +extern const unsigned char g_f8X16[]; + +typedef struct { + const unsigned char FontWidth; /*!< Font width in pixels */ + unsigned char FontHeight; /*!< Font height in pixels */ + const unsigned short *data; /*!< Pointer to data font data array */ +} FontDef; + +extern FontDef Font_7x10; +extern FontDef Font_6x8; +extern FontDef Font_11x18; +extern FontDef Font_16x26; + +#ifdef __cplusplus +} +#endif + +#endif // SSD1306_FONTS_H \ No newline at end of file diff --git a/src/vendor/test/led/CMakeLists.txt b/src/vendor/test/led/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8a521a9d7388c8283158a528854b359dd5537733 --- /dev/null +++ b/src/vendor/test/led/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/led_example.c" PARENT_SCOPE) diff --git a/src/vendor/test/led/README.md b/src/vendor/test/led/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2a8a6cdc10165abfbe654844f60fab5f139f1ae3 --- /dev/null +++ b/src/vendor/test/led/README.md @@ -0,0 +1,98 @@ +# LED + +## 1.1 介绍 + +**功能介绍:** 交通灯板上红色LED灯循环闪烁。 + +**软件概述:** GPIO引脚输出高低电平状态。 + +**硬件概述:** 核心板、交通灯板。通过交通灯板上丝印可以看出是RED与底板的D10相连,底板左边位置D10对应核心板上GPIO 7。硬件搭建要求如图所示: + + 参考[核心板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf)、[交通灯板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_SSL_VER.A.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf) + + image-20240415144302434 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 通过交通灯板上红色LED灯循环闪烁 + +## 1.4 接口介绍 + +### 1.4.1 uapi_gpio_set_dir() + +| **定义:** | errcode_t uapi_gpio_set_dir(pin_t pin, gpio_direction_t dir); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置GPIO的输入输出方向函数 | +| **参数:** | pin: io引脚
dir:输入输出方向 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +### 1.4.2 uapi_gpio_set_val() + +| 定义: | errcode_t uapi_gpio_set_val(pin_t pin, gpio_level_t level); | +| ------------ | ----------------------------------------------------------- | +| **功能:** | 设置GPIO的输出状态 | +| **参数:** | pin:io引脚
level:设置输出为高或低 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +### 1.4.3 uapi_gpio_toggle() + +| **定义:** | errcode_t uapi_gpio_toggle(pin_t pin); | +| ------------ | -------------------------------------- | +| **功能:** | 翻转输出GPIO电平状态. | +| **参数:** | pin:io引脚 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +## 1.5 具体实现 + + 步骤一:设置GPIO为输出模式; + + 步骤二:设置GPIO输出为高或低; + + 步骤三:翻转输出GPIO电平状态 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”led“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\led文件里面内容拷贝到**步骤一创建的Sample文件夹中”led“**。 + + ![image-20240415164754348](../../../docs/pic/led/image-20240415164754348.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support LED Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240415164817652 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七“软件烧录成功后,按一下开发板的RESET按键复位开发板,可以通过交通灯板上红色LED灯循环闪烁。 + + \ No newline at end of file diff --git a/src/vendor/test/led/led_example.c b/src/vendor/test/led/led_example.c new file mode 100644 index 0000000000000000000000000000000000000000..8cc5b21c24511e4d6ea7b2452d0ab4b280edbeb4 --- /dev/null +++ b/src/vendor/test/led/led_example.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "common_def.h" +#include "soc_osal.h" +#include "gpio.h" +#include "hal_gpio.h" +#include "test_suite_log.h" +#include "app_init.h" + +#define BLINKY_TASK_STACK_SIZE 0x1000 +#define BLINKY_TASK_PRIO 24 +#define BSP_LED 7 // RED +#define CONFIG_BLINKY_DURATION_50MS 50 + +static void *led_task(const char *arg) +{ + unused(arg); + uapi_pin_set_mode(BSP_LED, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(BSP_LED, GPIO_DIRECTION_OUTPUT); + uapi_gpio_set_val(BSP_LED, GPIO_LEVEL_LOW); + + while (1) { + osal_msleep(CONFIG_BLINKY_DURATION_50MS); + uapi_gpio_toggle(BSP_LED); + } + return NULL; +} + +static void led_entry(void) +{ + uint32_t ret; + osal_task *taskid; + // 创建任务调度 + osal_kthread_lock(); + // 创建任务 + taskid = osal_kthread_create((osal_kthread_handler)led_task, NULL, "led_task", BLINKY_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid, BLINKY_TASK_PRIO); + if (ret != OSAL_SUCCESS) { + printf("create task1 failed .\n"); + } + osal_kthread_unlock(); +} + +/* Run the blinky_entry. */ +app_run(led_entry); \ No newline at end of file diff --git a/src/vendor/test/message/CMakeLists.txt b/src/vendor/test/message/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..d5cf5253aa4703186dbc0bfb5b8eb740ba9231a6 --- /dev/null +++ b/src/vendor/test/message/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/message_queue_example.c" PARENT_SCOPE) diff --git a/src/vendor/test/message/README.md b/src/vendor/test/message/README.md new file mode 100644 index 0000000000000000000000000000000000000000..993aa4fdf1a29ccee7a904bbdf3b494045341dad --- /dev/null +++ b/src/vendor/test/message/README.md @@ -0,0 +1,115 @@ +## message + +## 1.1 介绍 + +**功能介绍:** 本实验内容实现了创建一个队列,两个任务,任务1调用发送接口发送消息,任务2通过接收接口接收消息。 + +**软件概述:** 队列又称消息队列,是一种常用于任务间通信的数据结构,实现了接收来自任务或中断的不固定长度的消息,接收方根据消息ID读取消息。系统中使用队列数据结构实现任务异步通信工作,具有如下特性: + - 消息以先进先出方式排队,支持异步读写工作方式。 + - 读队列和写队列都支持超时机制。 + - 发送消息类型由通信双方约定,可以允许不同长度(不超过队列节点最大值)消息。 + - 一个任务能够从任意一个消息队列接收和发送消息。 + - 多个任务能够从同一个消息队列接收和发送消息。 + - 当队列使用结束后,如果是动态申请的内存,需要通过释放内存函数回收。 + +**硬件概述:** 核心板。硬件搭建要求如图所示: + + image-20240401152853303 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + ![image-20240401174326792](../../../docs/pic/message/image-20240401174326792.png) + +## 1.4 接口说明 + +### 1.4.1 osal_msg_queue_creat() + +| **定义:** | int osal_msg_queue_create(const char *name, unsigned short queue_len, unsigned long *queue_id, unsigned int flags,unsigned short max_msgsize); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 创建消息队列 | +| **参数:** | name:消息队列名称
queue_len:队列长度。值范围为[1,0xffff]
queue_id:成功创建的队列控制结构的ID
flags:队列模式
max_msgsize:节点大小。值范围为[1,0xffff],注意节点不宜过大也不易过小,可以参考代码注释 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\msgqueue\osal_msgqueue.h | + +### 1.4.2 osal_msg_queue_delete() + +| 定义: | void osal_msg_queue_delete(unsigned long queue_id); | +| ------------ | --------------------------------------------------- | +| **功能:** | 删除消息队列 | +| **参数:** | queue_id:成功创建的队列控制结构的ID | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\msgqueue\osal_msgqueue.h | + +### 1.4.3 osal_msg_queue_write_copy() + +| **定义:** | int osal_msg_queue_write_copy(unsigned long queue_id, void *buffer_addr, unsigned int buffer_size, unsigned int timeout); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 发送消息到队列尾部 | +| **参数:** | queue_id:成功创建的队列控制结构的ID
buffer_addr:存储要写入的数据的起始地址
buffer_size:写入数据长度
timeout:超时时间 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\msgqueue\osal_msgqueue.h | + +### 1.4.4 osal_msg_queue_read_copy() + +| **定义:** | int osal_msg_queue_read_copy(unsigned long queue_id, void *buffer_addr, unsigned int *buffer_size,unsigned int timeout); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 阻塞接收信息,单位:ms | +| **参数:** | queue_id:成功创建的队列控制结构的ID
buffer_addr:读取数据的起始地址
buffer_size:读取数据长度
timeout:超时时间 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\msgqueue\osal_msgqueue.h | + +## 1.5 具体实现 + + 步骤一:创建一个队列,两个任务,任务1调用发送接口发送消息,任务二通过接收窗口接收消息。 + + 步骤二:通过osal_kthread_creat创建任务1和任务2。 + + 步骤三:通过osal_msg_queue_creat创建一个消息队列。 + + 步骤四:在任务1调用osal_msg_queue_write_copy发送消息。 + + 步骤五:在任务2调用osal_msg_queue_read_copy接收消息。 + +## 1.6实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”message“。 + + ![image-20240401152929178](../../../docs/pic/common/image-20240401152929178.png) + +- 步骤二:将open_cfbb\vendor\hispark\message文件里面内容拷贝到**步骤一创建的Sample文件夹中”message“**。 + + ![image-20240401184805703](../../../docs/pic/message/image-20240401184805703.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support A6_KERNAL_MESSAGE Sample”,点击Save,关闭弹窗。 + + image-20240401153033024image-20240401153046561image-20240401174241614 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240401153005118](../../../docs/pic/common/image-20240401153005118.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240401153012691](../../../docs/pic/common/image-20240401153012691.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240401153019843](../../../docs/pic/common/image-20240401153019843.png) + +- 步骤七:软件烧录成功后,按一下开发板的RESET按键复位开发板,烧录完成后,串口打印信息如下。 + + ![image-20240401174326792](../../../docs/pic/message/image-20240401174326792.png) \ No newline at end of file diff --git a/src/vendor/test/message/message_queue_example.c b/src/vendor/test/message/message_queue_example.c new file mode 100644 index 0000000000000000000000000000000000000000..35f9fa9c938313d5c3fd89d8c96fd655f459487b --- /dev/null +++ b/src/vendor/test/message/message_queue_example.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "common_def.h" +#include "soc_osal.h" +#include "osal_wait.h" +#include "app_init.h" + +#define MSESSAGE_TASK_SEND_PRIO 25 +#define MSESSAGE_TASK_RECV_PRIO 26 +#define MSESSAGE_TASK_PRIO 24 +#define MSESSAGE_TASK_STACK_SIZE 0x1000 +#define MSG_QUEUE_SIZE 18 // 每数据最大18字节 +#define MSG_MAX_LEN 18 // 可存储18条数据 + +static unsigned long g_msg_queue; +uint8_t abuf[] = "test is message x"; + +/* 任务1发送数据 */ +void example_send_task(void) +{ + printf("send task start\r\n"); + uint32_t i = 0, ret = 0; + uint32_t uwlen = sizeof(abuf); + while (i < 5) { + abuf[uwlen - 2] = '0' + i; + i++; + /*将abuf里的数据写入队列*/ + ret = osal_msg_queue_write_copy(g_msg_queue, abuf, sizeof(abuf), OSAL_WAIT_FOREVER); + if (ret != OSAL_SUCCESS) { + printf("send message failure,error:%#x\n", ret); + } + osal_msleep(5); + } +} + +/* 任务2接收数据 */ +void example_recv_task(void) +{ + printf("recv task start\r\n"); + uint8_t msg[2024]; + uint32_t ret = 0; + // 设置缓存去大小及存放数据读取的消息大小 + uint32_t msg_rev_size = 2024; + while (1) { + /* 读取队列里的数据存入msg里 */ + ret = osal_msg_queue_read_copy(g_msg_queue, msg, &msg_rev_size, OSAL_WAIT_FOREVER); + if (ret != OSAL_SUCCESS) { + printf("recv message failure,error:%#x\n", ret); + break; + } + printf("recv message:%s\r\n", (char *)msg); + osal_msleep(5); + } + /* 删除队列。需根据具体情况删除,大多数情况下无需删除队列,且在有任务占用等情况下删除队 + 列会导致失败。以下代码仅供API展示 */ + // osal_msg_queue_delete(g_msg_queue); + // printf("delete the queue success!\n"); +} + +void example_task_msg(void) +{ + uint32_t ret; + osal_task *taskid1, *taskid2; + ret = osal_msg_queue_create("name", MSG_QUEUE_SIZE, &g_msg_queue, 0, MSG_MAX_LEN); + if (ret != OSAL_SUCCESS) { + printf("create queue failure!,error:%x\n", ret); + } + printf("create the queue success! queue_id = %d\n", g_msg_queue); + // 创建任务1 + taskid1 = osal_kthread_create((osal_kthread_handler)example_send_task, NULL, "task1", MSESSAGE_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid1, MSESSAGE_TASK_SEND_PRIO); + if (ret != OSAL_SUCCESS) { + printf("create task1 failed .\n"); + } + // 创建任务2 + taskid2 = osal_kthread_create((osal_kthread_handler)example_recv_task, NULL, "task2", MSESSAGE_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid2, MSESSAGE_TASK_RECV_PRIO); + if (ret != OSAL_SUCCESS) { + printf("create task2 failed .\n"); + } +} + +static void example_task_entry_message(void) +{ + uint32_t ret; + osal_task *taskid; + osal_kthread_lock(); + taskid = osal_kthread_create((osal_kthread_handler)example_task_msg, NULL, "message", MSESSAGE_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid, MSESSAGE_TASK_PRIO); + if (ret != OSAL_SUCCESS) { + printf("create task1 failed .\n"); + } + osal_kthread_unlock(); +} + +/* Run the muxTask_entry. */ +app_run(example_task_entry_message); \ No newline at end of file diff --git a/src/vendor/test/mutex/CMakeLists.txt b/src/vendor/test/mutex/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..00674b0f9e1d2c11b3889c7e9136443dab8f3a7e --- /dev/null +++ b/src/vendor/test/mutex/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/mutex_example.c" PARENT_SCOPE) diff --git a/src/vendor/test/mutex/README.md b/src/vendor/test/mutex/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c43c9b708bd3627c547a19c3cfc4fffc871125be --- /dev/null +++ b/src/vendor/test/mutex/README.md @@ -0,0 +1,109 @@ +# mutex + +## 1.1 介绍 + +**功能介绍:** 本实验内容实现了防止两个任务在同一时刻访问相同共享资源。 + +**软件概述:** 互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理。任意时刻互斥锁的状态只有两种:闭锁,当有任务持有时,这个任务获得该互斥锁的所有权;开锁,当该任务释放它时,该互斥锁被开锁,任务失去该互斥锁的所有权。当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。 + +**硬件概述:** 核心板。硬件搭建要求如图所示: + + image-20240401152853303 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + ![image-20240401153146328](../../../docs/pic/mutex/image-20240401153146328.png) + +## 1.4 接口说明 + +### 1.4.1 osal_mutex_init() + +| **定义:** | int osal_mutex_init(osal_mutex *mutex); | +| ------------ | ----------------------------------------- | +| **功能:** | 初始化互斥锁 | +| **参数:** | mutex:互斥对象 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\mutex\osal_mutex.h | + +### 1.4.2 osal_mutex_destroy() + +| 定义: | void osal_mutex_destroy(osal_mutex *mutex); | +| ------------ | ------------------------------------------- | +| **功能:** | 删除指定的互斥锁 | +| **参数:** | mutex:互斥对象 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\mutex\osal_mutex.h | + +### 1.4.3 osal_mutex_lock_timeout() + +| **定义:** | int osal_mutex_lock_timeout(osal_mutex *mutex, unsigned int timeout); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 阻塞获取互斥锁,单位:ms | +| **参数:** | mutex:互斥对象
timeout:超时时间 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kkernel\osal\include\mutex\osal_mutex.h | + +### 1.4.4 osal_event_unlock() + +| **定义:** | void osal_mutex_unlock(osal_mutex *mutex); | +| ------------ | ------------------------------------------ | +| **功能:** | 释放指定互斥锁 | +| **参数:** | mutex:互斥对象 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\mutex\osal_mutex.h | + +## 1.5 具体实现 + + 步骤一:任务example_task_mux创建一个互斥锁,锁任务调度,创建两个任务example_mutex_task1、example_mutex_task2,example_mutex_task2优先级高于example_mutex_task1,解锁任务调度。 + + 步骤二:example_mutex_task2被调度,永久申请互斥锁,然后任务休眠100ms,example_mutex_task2挂起,example_mutex_task1被唤醒。 + + 步骤三:example_mutex_task1申请互斥锁,等待时间为10ms,因互斥锁仍被example_mutex_task2持有,example_mutex_task1挂起,10ms后未拿到互斥锁,example_mutex_task1被唤醒,试图以永久等待申请互斥锁,example_mutex_task1挂起。 + + 步骤四:100ms后example_mutex_task2唤醒,释放互斥锁后,example_mutex_task1被调度运行后释放互斥锁。 + + 步骤五:example_mutex_task1执行完,300ms后,删除互斥锁。 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”mutex“。 + + ![image-20240401152929178](../../../docs/pic/common/image-20240401152929178.png) + +- 步骤二:将open_cfbb\vendor\hispark\mutex文件里面内容拷贝到**步骤一创建的Sample文件夹中”mutex“**。 + + ![image-20240401155957848](../../../docs/pic/mutex/image-20240401155957848.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support MUTEX Sample”,点击Save,关闭弹窗。 + + image-20240401153033024image-20240401153046561image-20240401154052776 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240401153005118](../../../docs/pic/common/image-20240401153005118.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240401153012691](../../../docs/pic/common/image-20240401153012691.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240401153019843](../../../docs/pic/common/image-20240401153019843.png) + +- 步骤七:软件烧录成功后,按一下开发板的RESET按键复位开发板,烧录完成后,串口打印信息如下。 + + ![image-20240401153146328](../../../docs/pic/mutex/image-20240401153146328.png) \ No newline at end of file diff --git a/src/vendor/test/mutex/mutex_example.c b/src/vendor/test/mutex/mutex_example.c new file mode 100644 index 0000000000000000000000000000000000000000..e00c2cbee0fef2f45cb9b3f91f2807ef5d885215 --- /dev/null +++ b/src/vendor/test/mutex/mutex_example.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "common_def.h" +#include "soc_osal.h" +#include "osal_wait.h" +#include "app_init.h" + +#define TASK_PRI_TASK1 21 +#define TASK_PRI_TASK2 20 +#define MUX_TASK_STACK_SIZE 0x1000 +#define MUX_TASK_PRIO 17 +#define TASK_STACK_SIZE 0x1000 + +static osal_mutex g_mux_id; + +void example_mutex_task1(void) +{ + uint32_t ret; + printf("task1 try to get mutex,wait 10 ms.\n"); + ret = osal_mutex_lock_timeout(&g_mux_id, 10); + if (ret == OSAL_SUCCESS) { + printf("task1 get mutex g_mux_id.\n"); + osal_mutex_unlock(&g_mux_id); + } else { + printf("task1 timeout and try to get mutex, wait forever.\n"); + ret = osal_mutex_lock_timeout(&g_mux_id, OSAL_WAIT_FOREVER); + if (ret == OSAL_SUCCESS) { + printf("task1 wait forever,get mutex g_mux_id.\n"); + osal_mutex_unlock(&g_mux_id); + } + } +} + +void example_mutex_task2(void) +{ + printf("task2 try to get mutex, wait forever.\n"); + osal_mutex_lock_timeout(&g_mux_id, OSAL_WAIT_FOREVER); + printf("task2 get mutex g_mux_id and suspend 100 ms.\n"); + osal_msleep(100); + printf("task2 resumed and post the g_mux_id\n"); + osal_mutex_unlock(&g_mux_id); +} + +void example_task_mux(void) +{ + uint32_t ret; + osal_task *taskid1, *taskid2; + osal_mutex_init(&g_mux_id); + // 创建任务调度 + osal_kthread_lock(); + // 创建任务1 + taskid1 = osal_kthread_create((osal_kthread_handler)example_mutex_task1, NULL, "example_task1", TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid1, TASK_PRI_TASK1); + if (ret != OSAL_SUCCESS) { + printf("create task1 failed .\n"); + } + // 创建任务2 + taskid2 = osal_kthread_create((osal_kthread_handler)example_mutex_task2, NULL, "example_task2", TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid2, TASK_PRI_TASK2); + if (ret != OSAL_SUCCESS) { + printf("create task2 failed .\n"); + } + osal_kthread_unlock(); + // 延时3s回收资源 + osal_msleep(3000); + osal_mutex_destroy(&g_mux_id); +} + +static void example_task_entry_mux(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)example_task_mux, 0, "task_mux", MUX_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, MUX_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the muxTask_entry. */ +app_run(example_task_entry_mux); \ No newline at end of file diff --git a/src/vendor/test/oled/CMakeLists.txt b/src/vendor/test/oled/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..61a253cb73743639c4e554149164a13a3db567c5 --- /dev/null +++ b/src/vendor/test/oled/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/helloworld.c" "${CMAKE_CURRENT_SOURCE_DIR}/ssd1306_fonts.c" "${CMAKE_CURRENT_SOURCE_DIR}/ssd1306.c" PARENT_SCOPE) diff --git a/src/vendor/test/oled/README.md b/src/vendor/test/oled/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a23adceb3aa28dd63d3e88077b87b472cce2b909 --- /dev/null +++ b/src/vendor/test/oled/README.md @@ -0,0 +1,136 @@ +# OLED + +## 1.1 介绍 + +**功能介绍:** 在SSD1306 OLED屏幕显示“Hello World”。 + +**软件概述:** I2C是一种串行通信协议,允许将多个设备连接到一条总线上。每个连接到总线上的器件都有唯一地址,任何器件既可作为主机也可以作为从机,但同一时刻只允许有一个主机。 + +**硬件概述:** 核心板、OLED板,OLED数据手册参考:https://gitee.com/HiSpark/hi3861_hdu_iot_application/issues/I6WPSS?from=project-issue 里面的液晶显示器.pdf。 通过OLED板原理图可以看出OLED板SDA与底板TX、SCL与底板RX,底板左边TX对应核心板TXD1,底板左边RX对应核心板RXD1。硬件搭建要求如图所示: + + 参考[核心板板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf)、[OLED板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_OLED_VER.A.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf) + + image-20240415144302434 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.T100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 屏幕上显示“Hello World”。 + + ![image-20240415171821932](../../../docs/pic/oled/image-20240415171821932.png) + +## 1.4 接口介绍 + +### 1.4.1 uapi_i2c_master_read() + +| **定义:** | errcode_t uapi_i2c_master_read(i2c_bus_t bus, uint16_t dev_addr, i2c_data_t *data); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 主机接收来自目标I2C从机的数据,有两种方式,一种是手动切换方式,另外一种是自动切换模式,两种方式静态配置,手动切换方式一共有以下三种传输模式,但是不能在同一bus中同时使用 | +| **参数:** | bus:I2C总线
dev_addr:主机接收数据的目标从机地址
data:接收数据的数据指针 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\i2c.h | + +### 1.4.2 uapi_i2c_master_write() + +| 定义: | errcode_t uapi_i2c_master_write(i2c_bus_t bus, uint16_t dev_addr, i2c_data_t *data); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 将数据从主机写入到从机,有两种方式,一种是手动切换方式,另外一种是自动切换模式,两种方式静态配置,手动切换方式一共有以下三种传输模式,但是不能在同一bus中同时使用 | +| **参数:** | bus:I2C总线
dev_addr:主机接收数据的目标从机地址
data:发送数据的数据指针 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\i2c.h | + +### 1.4.3 uapi_i2c_master_init() + +| **定义:** | errcode_t uapi_i2c_master_init(i2c_bus_t bus, uint32_t baudrate, uint8_t hscode); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 根据指定的参数初始化该i2c为主机 | +| **参数:** | bus:I2C总线
baudrate:i2c波特率
hscode:i2c高速模式主机码,每个主机有自己唯一的主机码,有效取值范围0~7,仅在高速模式下需要配置 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\i2c.h | + +### 1.4.4 uapi_pin_set_mode() + +| **定义:** | errcode_t uapi_pin_set_mode(pin_t pin, pin_mode_t mode); | +| ------------ | -------------------------------------------------------- | +| **功能:** | 设置引脚复用模式 | +| **参数:** | pin:io
mode:复用模式 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pinctrl.h | + +### 1.4.5 ssd1306_SetCursor() + +| **定义:** | void ssd1306_SetCursor(uint8_t x, uint8_t y); | +| ------------ | --------------------------------------------- | +| **功能:** | 设置字符串显示位置 | +| **参数:** | x:横坐标
y:众坐标 | +| **返回值:** | 无返回值 | +| **依赖:** | oled\ssd1306.h | + +### 1.4.6 ssd1306_DrawString() + +| **定义:** | char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置输出的字符串 | +| **参数:** | str:要输出的字符串
Font:字符串大小
color:颜色 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | oled\ssd1306.h | + +### 1.4.7 ssd1306_UpdateScreen() + +| **定义:** | void ssd1306_UpdateScreen(void); | +| ------------ | -------------------------------- | +| **功能:** | 在屏幕显示字符串 | +| **参数:** | 无 | +| **返回值:** | 无 | +| **依赖:** | oled\ssd1306.h | + +## 1.5 具体实现 + + 步骤一:初始化I2C设备; + + 步骤二:I2C通信正常后,初始化OLED; + + 步骤三:通过数据手册中协议要求,发送数据 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”oled“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\oled文件里面内容拷贝到**步骤一创建的Sample文件夹中”oled“**。 + + ![image-20240415171655322](../../../docs/pic/oled/image-20240415171655322.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support OLED Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240415171718967 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七“软件烧录成功后,按一下开发板的RESET按键复位开发板,屏幕上显示Hello World!!!。 + + ![image-20240415171821932](../../../docs/pic/oled/image-20240415171821932.png) \ No newline at end of file diff --git a/src/vendor/test/oled/helloworld.c b/src/vendor/test/oled/helloworld.c new file mode 100644 index 0000000000000000000000000000000000000000..b59588b2013a806d97fa88d4b26f16bc6733b924 --- /dev/null +++ b/src/vendor/test/oled/helloworld.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "common_def.h" +#include "soc_osal.h" +#include "i2c.h" +#include "osal_debug.h" +#include "ssd1306_fonts.h" +#include "ssd1306.h" +#include "app_init.h" + +#define CONFIG_I2C_SCL_MASTER_PIN 15 +#define CONFIG_I2C_SDA_MASTER_PIN 16 +#define CONFIG_I2C_MASTER_PIN_MODE 2 +#define I2C_MASTER_ADDR 0x0 +#define I2C_SLAVE1_ADDR 0x38 +#define I2C_SET_BANDRATE 400000 +#define I2C_TASK_STACK_SIZE 0x1000 +#define I2C_TASK_PRIO 17 + +void app_i2c_init_pin(void) +{ + uapi_pin_set_mode(CONFIG_I2C_SCL_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_I2C_SDA_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE); +} + +void OledTask(void) +{ + uint32_t baudrate = I2C_SET_BANDRATE; + uint32_t hscode = I2C_MASTER_ADDR; + app_i2c_init_pin(); + errcode_t ret = uapi_i2c_master_init(1, baudrate, hscode); + if (ret != 0) { + printf("i2c init failed, ret = %0x\r\n", ret); + } + ssd1306_Init(); + ssd1306_Fill(Black); + ssd1306_SetCursor(0, 0); + ssd1306_DrawString("Hello World!!!", Font_7x10, White); + ssd1306_UpdateScreen(); +} + +void oled_entry(void) +{ + uint32_t ret; + osal_task *taskid; + // 创建任务调度 + osal_kthread_lock(); + // 创建任务1 + taskid = osal_kthread_create((osal_kthread_handler)OledTask, NULL, "OledTask", I2C_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid, I2C_TASK_PRIO); + if (ret != OSAL_SUCCESS) { + printf("create task1 failed .\n"); + } + osal_kthread_unlock(); +} + +app_run(oled_entry); \ No newline at end of file diff --git a/src/vendor/test/oled/ssd1306.c b/src/vendor/test/oled/ssd1306.c new file mode 100644 index 0000000000000000000000000000000000000000..e7c4dab13006eb2a6cfd7513fa37f76b2489776e --- /dev/null +++ b/src/vendor/test/oled/ssd1306.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 +#include +#include +#include +#include +#include +#include +#include "i2c.h" +#include "soc_osal.h" +#include "ssd1306.h" + +#define CONFIG_I2C_MASTER_BUS_ID 1 +#define I2C_SLAVE2_ADDR 0x3C +#define SSD1306_CTRL_CMD 0x00 +#define SSD1306_CTRL_DATA 0x40 +#define SSD1306_MASK_CONT (0x1 << 7) +#define DOUBLE 2 + +void ssd1306_Reset(void) +{ + // Wait for the screen to boot,1ms The delay here is very important + osal_mdelay(1); +} + +static uint32_t ssd1306_SendData(uint8_t *buffer, uint32_t size) +{ + uint16_t dev_addr = I2C_SLAVE2_ADDR; + i2c_data_t data = {0}; + data.send_buf = buffer; + data.send_len = size; + uint32_t retval = uapi_i2c_master_write(CONFIG_I2C_MASTER_BUS_ID, dev_addr, &data); + if (retval != 0) { + printf("I2cWrite(%02X) failed, %0X!\n", data.send_buf[1], retval); + return retval; + } + return 0; +} + +static uint32_t ssd1306_WiteByte(uint8_t regAddr, uint8_t byte) +{ + uint8_t buffer[] = {regAddr, byte}; + return ssd1306_SendData(buffer, sizeof(buffer)); +} + +// Send a byte to the command register +void ssd1306_WriteCommand(uint8_t byte) +{ + ssd1306_WiteByte(SSD1306_CTRL_CMD, byte); +} + +// Send data +void ssd1306_WriteData(uint8_t *buffer, uint32_t buff_size) +{ + uint8_t data[SSD1306_WIDTH * DOUBLE] = {0}; + for (uint32_t i = 0; i < buff_size; i++) { + data[i * DOUBLE] = SSD1306_CTRL_DATA | SSD1306_MASK_CONT; + data[i * DOUBLE + 1] = buffer[i]; + } + data[(buff_size - 1) * DOUBLE] = SSD1306_CTRL_DATA; + ssd1306_SendData(data, sizeof(data)); +} + +// Screenbuffer +static uint8_t SSD1306_Buffer[SSD1306_BUFFER_SIZE]; + +// Screen object +static SSD1306_t SSD1306; + +/* Fills the Screenbuffer with values from a given buffer of a fixed length */ +SSD1306_Error_t ssd1306_FillBuffer(uint8_t *buf, uint32_t len) +{ + SSD1306_Error_t ret = SSD1306_ERR; + if (len <= SSD1306_BUFFER_SIZE) { + memcpy_s(SSD1306_Buffer, len + 1, buf, len); + ret = SSD1306_OK; + } + return ret; +} + +void ssd1306_Init_CMD(void) +{ + ssd1306_WriteCommand(0xA4); // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content + + ssd1306_WriteCommand(0xD3); // -set display offset - CHECK + ssd1306_WriteCommand(0x00); // -not offset + + ssd1306_WriteCommand(0xD5); // --set display clock divide ratio/oscillator frequency + ssd1306_WriteCommand(0xF0); // --set divide ratio + + ssd1306_WriteCommand(0xD9); // --set pre-charge period + ssd1306_WriteCommand(0x11); // 0x22 by default + + ssd1306_WriteCommand(0xDA); // --set com pins hardware configuration - CHECK +#if (SSD1306_HEIGHT == 32) + ssd1306_WriteCommand(0x02); +#elif (SSD1306_HEIGHT == 64) + ssd1306_WriteCommand(0x12); +#elif (SSD1306_HEIGHT == 128) + ssd1306_WriteCommand(0x12); +#else +#error "Only 32, 64, or 128 lines of height are supported!" +#endif + + ssd1306_WriteCommand(0xDB); // --set vcomh + ssd1306_WriteCommand(0x30); // 0x20,0.77xVcc, 0x30,0.83xVcc + + ssd1306_WriteCommand(0x8D); // --set DC-DC enable + ssd1306_WriteCommand(0x14); // + ssd1306_SetDisplayOn(1); // --turn on SSD1306 panel +} + +// Initialize the oled screen +void ssd1306_Init(void) +{ + // Reset OLED + ssd1306_Reset(); + // Init OLED + ssd1306_SetDisplayOn(0); // display off + + ssd1306_WriteCommand(0x20); // Set Memory Addressing Mode + ssd1306_WriteCommand(0x00); // 00b,Horizontal Addressing Mode; 01b,Vertical Addressing Mode; + // 10b,Page Addressing Mode (RESET); 11b,Invalid + + ssd1306_WriteCommand(0xB0); // Set Page Start Address for Page Addressing Mode,0-7 + +#ifdef SSD1306_MIRROR_VERT + ssd1306_WriteCommand(0xC0); // Mirror vertically +#else + ssd1306_WriteCommand(0xC8); // Set COM Output Scan Direction +#endif + + ssd1306_WriteCommand(0x00); // ---set low column address + ssd1306_WriteCommand(0x10); // ---set high column address + + ssd1306_WriteCommand(0x40); // --set start line address - CHECK + + ssd1306_SetContrast(0xFF); + +#ifdef SSD1306_MIRROR_HORIZ + ssd1306_WriteCommand(0xA0); // Mirror horizontally +#else + ssd1306_WriteCommand(0xA1); // --set segment re-map 0 to 127 - CHECK +#endif + +#ifdef SSD1306_INVERSE_COLOR + ssd1306_WriteCommand(0xA7); // --set inverse color +#else + ssd1306_WriteCommand(0xA6); // --set normal color +#endif + +// Set multiplex ratio. +#if (SSD1306_HEIGHT == 128) + // Found in the Luma Python lib for SH1106. + ssd1306_WriteCommand(0xFF); +#else + ssd1306_WriteCommand(0xA8); // --set multiplex ratio(1 to 64) - CHECK +#endif + +#if (SSD1306_HEIGHT == 32) + ssd1306_WriteCommand(0x1F); // +#elif (SSD1306_HEIGHT == 64) + ssd1306_WriteCommand(0x3F); // +#elif (SSD1306_HEIGHT == 128) + ssd1306_WriteCommand(0x3F); // Seems to work for 128px high displays too. +#else +#error "Only 32, 64, or 128 lines of height are supported!" +#endif + ssd1306_Init_CMD(); + // Clear screen + ssd1306_Fill(Black); + + // Flush buffer to screen + ssd1306_UpdateScreen(); + + // Set default values for screen object + SSD1306.CurrentX = 0; + SSD1306.CurrentY = 0; + + SSD1306.Initialized = 1; +} + +// Fill the whole screen with the given color +void ssd1306_Fill(SSD1306_COLOR color) +{ + /* Set memory */ + uint32_t i; + + for (i = 0; i < sizeof(SSD1306_Buffer); i++) { + SSD1306_Buffer[i] = (color == Black) ? 0x00 : 0xFF; + } +} + +// Write the screenbuffer with changed to the screen +void ssd1306_UpdateScreen(void) +{ + // Write data to each page of RAM. Number of pages + // depends on the screen height: + // + // * 32px == 4 pages + // * 64px == 8 pages + // * 128px == 16 pages + + uint8_t cmd[] = { + 0X21, // 设置列起始和结束地址 + 0X00, // 列起始地址 0 + 0X7F, // 列终止地址 127 + 0X22, // 设置页起始和结束地址 + 0X00, // 页起始地址 0 + 0X07, // 页终止地址 7 + }; + uint32_t count = 0; + uint8_t data[sizeof(cmd) * DOUBLE + SSD1306_BUFFER_SIZE + 1] = {}; + + // copy cmd + for (uint32_t i = 0; i < sizeof(cmd) / sizeof(cmd[0]); i++) { + data[count++] = SSD1306_CTRL_CMD | SSD1306_MASK_CONT; + data[count++] = cmd[i]; + } + + // copy frame data + data[count++] = SSD1306_CTRL_DATA; + memcpy_s(&data[count], SSD1306_BUFFER_SIZE + 1, SSD1306_Buffer, SSD1306_BUFFER_SIZE); + count += sizeof(SSD1306_Buffer); + + // send to i2c bus + uint32_t retval = ssd1306_SendData(data, count); + if (retval != 0) { + printf("ssd1306_UpdateScreen send frame data filed: %d!\r\n", retval); + } +} + +// Draw one pixel in the screenbuffer +// X => X Coordinate +// Y => Y Coordinate +// color => Pixel color +void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color) +{ + if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) { + // Don't write outside the buffer + return; + } + SSD1306_COLOR color1 = color; + // Check if pixel should be inverted + if (SSD1306.Inverted) { + color1 = (SSD1306_COLOR)!color1; + } + + // Draw in the right color + uint32_t c = 8; // 8 + if (color == White) { + SSD1306_Buffer[x + (y / c) * SSD1306_WIDTH] |= 1 << (y % c); + } else { + SSD1306_Buffer[x + (y / c) * SSD1306_WIDTH] &= ~(1 << (y % c)); + } +} + +// Draw 1 char to the screen buffer +// ch => char om weg te schrijven +// Font => Font waarmee we gaan schrijven +// color => Black or White +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color) +{ + uint32_t i, b, j; + + // Check if character is valid + uint32_t ch_min = 32; // 32 + uint32_t ch_max = 126; // 126 + if ((uint32_t)ch < ch_min || (uint32_t)ch > ch_max) { + return 0; + } + + // Check remaining space on current line + if (SSD1306_WIDTH < (SSD1306.CurrentX + Font.FontWidth) || SSD1306_HEIGHT < (SSD1306.CurrentY + Font.FontHeight)) { + // Not enough space on current line + return 0; + } + + // Use the font to write + for (i = 0; i < Font.FontHeight; i++) { + b = Font.data[(ch - ch_min) * Font.FontHeight + i]; + for (j = 0; j < Font.FontWidth; j++) { + if ((b << j) & 0x8000) { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)color); + } else { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color); + } + } + } + + // The current space is now taken + SSD1306.CurrentX += Font.FontWidth; + + // Return written char for validation + return ch; +} + +// Write full string to screenbuffer +char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color) +{ + // Write until null-byte + char *str1 = str; + while (*str1) { + if (ssd1306_DrawChar(*str1, Font, color) != *str1) { + // Char could not be written + return *str1; + } + // Next char + str1++; + } + + // Everything ok + return *str1; +} + +// Position the cursor +void ssd1306_SetCursor(uint8_t x, uint8_t y) +{ + SSD1306.CurrentX = x; + SSD1306.CurrentY = y; +} + +// Draw line by Bresenhem's algorithm +void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) +{ + uint8_t x = x1; + uint8_t y = y1; + int32_t deltaX = abs(x2 - x1); + int32_t deltaY = abs(y2 - y1); + int32_t signX = ((x1 < x2) ? 1 : -1); + int32_t signY = ((y1 < y2) ? 1 : -1); + int32_t error = deltaX - deltaY; + int32_t error2; + ssd1306_DrawPixel(x2, y2, color); + while ((x1 != x2) || (y1 != y2)) { + ssd1306_DrawPixel(x1, y1, color); + error2 = error * DOUBLE; + if (error2 > -deltaY) { + error -= deltaY; + x += signX; + } else { + /* nothing to do */ + } + if (error2 < deltaX) { + error += deltaX; + y += signY; + } else { + /* nothing to do */ + } + } +} + +// Draw polyline +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color) +{ + uint16_t i; + if (par_vertex != 0) { + for (i = 1; i < par_size; i++) { + ssd1306_DrawLine(par_vertex[i - 1].x, par_vertex[i - 1].y, par_vertex[i].x, par_vertex[i].y, color); + } + } else { + /* nothing to do */ + } + return; +} + +// Draw circle by Bresenhem's algorithm +void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color) +{ + int32_t x = -par_r; + int32_t y = 0; + int32_t b = 2; + int32_t err = b - b * par_r; + int32_t e2; + + if (par_x >= SSD1306_WIDTH || par_y >= SSD1306_HEIGHT) { + return; + } + + do { + ssd1306_DrawPixel(par_x - x, par_y + y, par_color); + ssd1306_DrawPixel(par_x + x, par_y + y, par_color); + ssd1306_DrawPixel(par_x + x, par_y - y, par_color); + ssd1306_DrawPixel(par_x - x, par_y - y, par_color); + e2 = err; + if (e2 <= y) { + y++; + err = err + (y * b + 1); + if (-x == y && e2 <= x) { + e2 = 0; + } else { + /* nothing to do */ + } + } else { + /* nothing to do */ + } + if (e2 > x) { + x++; + err = err + (x * b + 1); + } else { + /* nothing to do */ + } + } while (x <= 0); + + return; +} + +// Draw rectangle +void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) +{ + ssd1306_DrawLine(x1, y1, x2, y1, color); + ssd1306_DrawLine(x2, y1, x2, y2, color); + ssd1306_DrawLine(x2, y2, x1, y2, color); + ssd1306_DrawLine(x1, y2, x1, y1, color); +} + +void ssd1306_DrawBitmap(const uint8_t *bitmap, uint32_t size) +{ + unsigned int c = 8; + uint8_t rows = size * c / SSD1306_WIDTH; + if (rows > SSD1306_HEIGHT) { + rows = SSD1306_HEIGHT; + } + for (uint8_t y = 0; y < rows; y++) { + for (uint8_t x = 0; x < SSD1306_WIDTH; x++) { + uint8_t byte = bitmap[(y * SSD1306_WIDTH / c) + (x / c)]; + uint8_t bit = byte & (0x80 >> (x % c)); + ssd1306_DrawPixel(x, y, bit ? White : Black); + } + } +} + +void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data, uint32_t size) +{ + uint32_t stride = w; + uint8_t h = w; // 字体宽高一样 + uint8_t width = w; + if (x + w > SSD1306_WIDTH || y + h > SSD1306_HEIGHT || w * h == 0) { + printf("%dx%d @ %d,%d out of range or invalid!\r\n", w, h, x, y); + return; + } + + width = (width <= SSD1306_WIDTH ? width : SSD1306_WIDTH); + h = (h <= SSD1306_HEIGHT ? h : SSD1306_HEIGHT); + stride = (stride == 0 ? w : stride); + unsigned int c = 8; + + uint8_t rows = size * c / stride; + for (uint8_t i = 0; i < rows; i++) { + uint32_t base = i * stride / c; + for (uint8_t j = 0; j < width; j++) { + uint32_t idx = base + (j / c); + uint8_t byte = idx < size ? data[idx] : 0; + uint8_t bit = byte & (0x80 >> (j % c)); + ssd1306_DrawPixel(x + j, y + i, bit ? White : Black); + } + } +} + +void ssd1306_SetContrast(const uint8_t value) +{ + const uint8_t kSetContrastControlRegister = 0x81; + ssd1306_WriteCommand(kSetContrastControlRegister); + ssd1306_WriteCommand(value); +} + +void ssd1306_SetDisplayOn(const uint8_t on) +{ + uint8_t value; + if (on) { + value = 0xAF; // Display on + SSD1306.DisplayOn = 1; + } else { + value = 0xAE; // Display off + SSD1306.DisplayOn = 0; + } + ssd1306_WriteCommand(value); +} + +uint8_t ssd1306_GetDisplayOn(void) +{ + return SSD1306.DisplayOn; +} + +int g_ssd1306_current_loc_v = 0; +#define SSD1306_INTERVAL_V (15) + +void ssd1306_ClearOLED(void) +{ + ssd1306_Fill(Black); + g_ssd1306_current_loc_v = 0; +} + +void ssd1306_printf(char *fmt, ...) +{ + char buffer[20]; + int ret = 0; + if (fmt) { + va_list argList; + va_start(argList, fmt); + ret = vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), fmt, argList); + if (ret < 0) { + printf("buffer is null\r\n"); + } + va_end(argList); + ssd1306_SetCursor(0, g_ssd1306_current_loc_v); + ssd1306_DrawString(buffer, Font_7x10, White); + + ssd1306_UpdateScreen(); + } + g_ssd1306_current_loc_v += SSD1306_INTERVAL_V; +} diff --git a/src/vendor/test/oled/ssd1306.h b/src/vendor/test/oled/ssd1306.h new file mode 100644 index 0000000000000000000000000000000000000000..769f19c7af3a3aaf0f6fd007d62721c007b0e7d1 --- /dev/null +++ b/src/vendor/test/oled/ssd1306.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 SSD1306_H +#define SSD1306_H + +#include +#include +#include "ssd1306_fonts.h" + +// SSD1306 OLED height in pixels +#ifndef SSD1306_HEIGHT +#define SSD1306_HEIGHT 64 +#endif + +// SSD1306 width in pixels +#ifndef SSD1306_WIDTH +#define SSD1306_WIDTH 128 +#endif + +// some LEDs don't display anything in first two columns + +#ifndef SSD1306_BUFFER_SIZE +#define SSD1306_BUFFER_SIZE (SSD1306_WIDTH * SSD1306_HEIGHT / 8) +#endif + +// Enumeration for screen colors +typedef enum { + Black = 0x00, // Black color, no pixel + White = 0x01 // Pixel is set. Color depends on OLED +} SSD1306_COLOR; + +typedef enum { + SSD1306_OK = 0x00, + SSD1306_ERR = 0x01 // Generic error. +} SSD1306_Error_t; + +// Struct to store transformations +typedef struct { + uint16_t CurrentX; + uint16_t CurrentY; + uint8_t Inverted; + uint8_t Initialized; + uint8_t DisplayOn; +} SSD1306_t; +typedef struct { + uint8_t x; + uint8_t y; +} SSD1306_VERTEX; + +// Procedure definitions +void ssd1306_Init(void); +void ssd1306_Fill(SSD1306_COLOR color); +void ssd1306_SetCursor(uint8_t x, uint8_t y); +void ssd1306_UpdateScreen(void); + +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color); +char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color); + +void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color); +void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color); +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color); +void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color); +void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color); +void ssd1306_DrawBitmap(const uint8_t *bitmap, uint32_t size); +void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data, uint32_t size); + +/** + * @brief Sets the contrast of the display. + * @param[in] value contrast to set. + * @note Contrast increases as the value increases. + * @note RESET = 7Fh. + */ +void ssd1306_SetContrast(const uint8_t value); +/** + * @brief Set Display ON/OFF. + * @param[in] on 0 for OFF, any for ON. + */ +void ssd1306_SetDisplayOn(const uint8_t on); +/** + * @brief Reads DisplayOn state. + * @return 0: OFF. + * 1: ON. + */ +uint8_t ssd1306_GetDisplayOn(void); + +// Low-level procedures +void ssd1306_Reset(void); +void ssd1306_WriteCommand(uint8_t byte); +void ssd1306_WriteData(uint8_t *buffer, size_t buff_size); +SSD1306_Error_t ssd1306_FillBuffer(uint8_t *buf, uint32_t len); +void ssd1306_ClearOLED(void); +void ssd1306_printf(char *fmt, ...); + +#endif // __SSD1306_H__ \ No newline at end of file diff --git a/src/vendor/test/oled/ssd1306_fonts.c b/src/vendor/test/oled/ssd1306_fonts.c new file mode 100644 index 0000000000000000000000000000000000000000..8053265cdef8a0474cc3506121ce65c54cc06d6f --- /dev/null +++ b/src/vendor/test/oled/ssd1306_fonts.c @@ -0,0 +1,819 @@ +/* + MIT License + + Copyright (c) 2018-2019, Alexey Dynda + + 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. +*/ +/* + * ssd1306xled_font6x8 is by Neven Boyanov + * ssd1306xled_font8x16 is by Neven Boyanov + * + * @created: 2014-08-12 + * @author: Neven Boyanov + * + * Copyright (c) 2015 Neven Boyanov, Tinusaur Team. All Rights Reserved. + * Distributed as open source software under MIT License, see LICENSE.txt file. + * Please, as a favour, retain the link http://tinusaur.org to The Tinusaur Project. + * + * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled + * + */ + +#include "ssd1306_fonts.h" + +/************************************6*8的点阵************************************/ +const unsigned char g_f6X8[][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // sp + {0x00, 0x00, 0x00, 0x2f, 0x00, 0x00}, // ! + {0x00, 0x00, 0x07, 0x00, 0x07, 0x00}, // " + {0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14}, // # + {0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12}, // $ + {0x00, 0x62, 0x64, 0x08, 0x13, 0x23}, // % + {0x00, 0x36, 0x49, 0x55, 0x22, 0x50}, // & + {0x00, 0x00, 0x05, 0x03, 0x00, 0x00}, // ' + {0x00, 0x00, 0x1c, 0x22, 0x41, 0x00}, // ( + {0x00, 0x00, 0x41, 0x22, 0x1c, 0x00}, // ) + {0x00, 0x14, 0x08, 0x3E, 0x08, 0x14}, // * + {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // + + {0x00, 0x00, 0x00, 0xA0, 0x60, 0x00}, // , + {0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // - + {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // . + {0x00, 0x20, 0x10, 0x08, 0x04, 0x02}, // / + {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0 + {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00}, // 1 + {0x00, 0x42, 0x61, 0x51, 0x49, 0x46}, // 2 + {0x00, 0x21, 0x41, 0x45, 0x4B, 0x31}, // 3 + {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10}, // 4 + {0x00, 0x27, 0x45, 0x45, 0x45, 0x39}, // 5 + {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6 + {0x00, 0x01, 0x71, 0x09, 0x05, 0x03}, // 7 + {0x00, 0x36, 0x49, 0x49, 0x49, 0x36}, // 8 + {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E}, // 9 + {0x00, 0x00, 0x36, 0x36, 0x00, 0x00}, // : + {0x00, 0x00, 0x56, 0x36, 0x00, 0x00}, // ;号 + {0x00, 0x08, 0x14, 0x22, 0x41, 0x00}, // < + {0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // = + {0x00, 0x00, 0x41, 0x22, 0x14, 0x08}, // > + {0x00, 0x02, 0x01, 0x51, 0x09, 0x06}, // ? + {0x00, 0x32, 0x49, 0x59, 0x51, 0x3E}, // @ + {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C}, // A + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36}, // B + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22}, // C + {0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C}, // D + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41}, // E + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01}, // F + {0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A}, // G + {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F}, // H + {0x00, 0x00, 0x41, 0x7F, 0x41, 0x00}, // I + {0x00, 0x20, 0x40, 0x41, 0x3F, 0x01}, // J + {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41}, // K + {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40}, // L + {0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F}, // M + {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F}, // N + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E}, // O + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x06}, // P + {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q + {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46}, // R + {0x00, 0x46, 0x49, 0x49, 0x49, 0x31}, // S + {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01}, // T + {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F}, // U + {0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F}, // V + {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F}, // W + {0x00, 0x63, 0x14, 0x08, 0x14, 0x63}, // X + {0x00, 0x07, 0x08, 0x70, 0x08, 0x07}, // Y + {0x00, 0x61, 0x51, 0x49, 0x45, 0x43}, // Z + {0x00, 0x00, 0x7F, 0x41, 0x41, 0x00}, // [ + {0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55}, // 55 + {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ] + {0x00, 0x04, 0x02, 0x01, 0x02, 0x04}, // ^ + {0x00, 0x40, 0x40, 0x40, 0x40, 0x40}, // _ + {0x00, 0x00, 0x01, 0x02, 0x04, 0x00}, // ' + {0x00, 0x20, 0x54, 0x54, 0x54, 0x78}, // a + {0x00, 0x7F, 0x48, 0x44, 0x44, 0x38}, // b + {0x00, 0x38, 0x44, 0x44, 0x44, 0x20}, // c + {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F}, // d + {0x00, 0x38, 0x54, 0x54, 0x54, 0x18}, // e + {0x00, 0x08, 0x7E, 0x09, 0x01, 0x02}, // f + {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C}, // g + {0x00, 0x7F, 0x08, 0x04, 0x04, 0x78}, // h + {0x00, 0x00, 0x44, 0x7D, 0x40, 0x00}, // i + {0x00, 0x40, 0x80, 0x84, 0x7D, 0x00}, // j + {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // k + {0x00, 0x00, 0x41, 0x7F, 0x40, 0x00}, // l + {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78}, // m + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x78}, // n + {0x00, 0x38, 0x44, 0x44, 0x44, 0x38}, // o + {0x00, 0xFC, 0x24, 0x24, 0x24, 0x18}, // p + {0x00, 0x18, 0x24, 0x24, 0x18, 0xFC}, // q + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x08}, // r + {0x00, 0x48, 0x54, 0x54, 0x54, 0x20}, // s + {0x00, 0x04, 0x3F, 0x44, 0x40, 0x20}, // t + {0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C}, // u + {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C}, // v + {0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C}, // w + {0x00, 0x44, 0x28, 0x10, 0x28, 0x44}, // x + {0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C}, // y + {0x00, 0x44, 0x64, 0x54, 0x4C, 0x44}, // z + {0x14, 0x14, 0x14, 0x14, 0x14, 0x14}, // horiz lines +}; + +/****************************************8*16的点阵************************************/ +const unsigned char g_f8X16[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, // ! 1 + 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " 2 + 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // # 3 + 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, // $ 4 + 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, // % 5 + 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, // & 6 + 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ' 7 + 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, // ( 8 + 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, // ) 9 + 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, // * 10 + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, // + 11 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // , 12 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // - 13 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // . 14 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, // / 15 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 16 + 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 17 + 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 18 + 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 19 + 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 20 + 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 21 + 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 22 + 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 23 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 24 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 25 + 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, // : 26 + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, // ;号 27 + 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, // < 28 + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, // = 29 + 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // > 30 + 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, // ? 31 + 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, // @ 32 + 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 33 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 34 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 35 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 36 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 37 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 38 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 39 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 40 + 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 41 + 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 42 + 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 43 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 44 + 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 45 + 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 46 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 47 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 48 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 49 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 50 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 51 + 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 52 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 53 + 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 54 + 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 55 + 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 56 + 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 57 + 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 58 + 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, // [ 59 + 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, // \ 60 + 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, // ] 61 + 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^ 62 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // _ 63 + 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ` 64 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 65 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 66 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 67 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 68 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 69 + 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 70 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 71 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 72 + 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 73 + 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 74 + 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 75 + 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 76 + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 77 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 78 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 79 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 80 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 81 + 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 82 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 83 + 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 84 + 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 85 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 86 + 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 87 + 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 88 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 89 + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 90 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, // { 91 + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // | 92 + 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, // } 93 + 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ~ 94 +}; + +static const unsigned short Font7x10[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ! + 0x2800, 0x2800, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x2400, 0x2400, 0x7C00, 0x2400, 0x4800, 0x7C00, 0x4800, 0x4800, 0x0000, 0x0000, // # + 0x3800, 0x5400, 0x5000, 0x3800, 0x1400, 0x5400, 0x5400, 0x3800, 0x1000, 0x0000, // $ + 0x2000, 0x5400, 0x5800, 0x3000, 0x2800, 0x5400, 0x1400, 0x0800, 0x0000, 0x0000, // % + 0x1000, 0x2800, 0x2800, 0x1000, 0x3400, 0x4800, 0x4800, 0x3400, 0x0000, 0x0000, // & + 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x0800, 0x1000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x1000, 0x0800, // ( + 0x2000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x1000, 0x2000, // ) + 0x1000, 0x3800, 0x1000, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * + 0x0000, 0x0000, 0x1000, 0x1000, 0x7C00, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // , + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3800, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // . + 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x0000, 0x0000, // / + 0x3800, 0x4400, 0x4400, 0x5400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 0 + 0x1000, 0x3000, 0x5000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // 1 + 0x3800, 0x4400, 0x4400, 0x0400, 0x0800, 0x1000, 0x2000, 0x7C00, 0x0000, 0x0000, // 2 + 0x3800, 0x4400, 0x0400, 0x1800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 3 + 0x0800, 0x1800, 0x2800, 0x2800, 0x4800, 0x7C00, 0x0800, 0x0800, 0x0000, 0x0000, // 4 + 0x7C00, 0x4000, 0x4000, 0x7800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 5 + 0x3800, 0x4400, 0x4000, 0x7800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 6 + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, // 7 + 0x3800, 0x4400, 0x4400, 0x3800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 8 + 0x3800, 0x4400, 0x4400, 0x4400, 0x3C00, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 9 + 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ; + 0x0000, 0x0000, 0x0C00, 0x3000, 0x4000, 0x3000, 0x0C00, 0x0000, 0x0000, 0x0000, // < + 0x0000, 0x0000, 0x0000, 0x7C00, 0x0000, 0x7C00, 0x0000, 0x0000, 0x0000, 0x0000, // = + 0x0000, 0x0000, 0x6000, 0x1800, 0x0400, 0x1800, 0x6000, 0x0000, 0x0000, 0x0000, // > + 0x3800, 0x4400, 0x0400, 0x0800, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ? + 0x3800, 0x4400, 0x4C00, 0x5400, 0x5C00, 0x4000, 0x4000, 0x3800, 0x0000, 0x0000, // @ + 0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000, // A + 0x7800, 0x4400, 0x4400, 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x0000, 0x0000, // B + 0x3800, 0x4400, 0x4000, 0x4000, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // C + 0x7000, 0x4800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4800, 0x7000, 0x0000, 0x0000, // D + 0x7C00, 0x4000, 0x4000, 0x7C00, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // E + 0x7C00, 0x4000, 0x4000, 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // F + 0x3800, 0x4400, 0x4000, 0x4000, 0x5C00, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // G + 0x4400, 0x4400, 0x4400, 0x7C00, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // H + 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3800, 0x0000, 0x0000, // I + 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // J + 0x4400, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // K + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // L + 0x4400, 0x6C00, 0x6C00, 0x5400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // M + 0x4400, 0x6400, 0x6400, 0x5400, 0x5400, 0x4C00, 0x4C00, 0x4400, 0x0000, 0x0000, // N + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // O + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // P + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x5400, 0x3800, 0x0400, 0x0000, // Q + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // R + 0x3800, 0x4400, 0x4000, 0x3000, 0x0800, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // S + 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // T + 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // U + 0x4400, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x1000, 0x0000, 0x0000, // V + 0x4400, 0x4400, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // W + 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, // X + 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // Y + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // Z + 0x1800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1800, // [ + 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0000, 0x0000, /* \ */ + 0x3000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3000, // ] + 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE00, // _ + 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x3800, 0x4400, 0x3C00, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // a + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x0000, 0x0000, // b + 0x0000, 0x0000, 0x3800, 0x4400, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // c + 0x0400, 0x0400, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // d + 0x0000, 0x0000, 0x3800, 0x4400, 0x7C00, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // e + 0x0C00, 0x1000, 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // f + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x7800, // g + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // h + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // i + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xE000, // j + 0x4000, 0x4000, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4400, 0x0000, 0x0000, // k + 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // l + 0x0000, 0x0000, 0x7800, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x0000, 0x0000, // m + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // n + 0x0000, 0x0000, 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // o + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x4000, 0x4000, // p + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x0400, // q + 0x0000, 0x0000, 0x5800, 0x6400, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // r + 0x0000, 0x0000, 0x3800, 0x4400, 0x3000, 0x0800, 0x4400, 0x3800, 0x0000, 0x0000, // s + 0x2000, 0x2000, 0x7800, 0x2000, 0x2000, 0x2000, 0x2000, 0x1800, 0x0000, 0x0000, // t + 0x0000, 0x0000, 0x4400, 0x4400, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // u + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x0000, 0x0000, // v + 0x0000, 0x0000, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // w + 0x0000, 0x0000, 0x4400, 0x2800, 0x1000, 0x1000, 0x2800, 0x4400, 0x0000, 0x0000, // x + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x6000, // y + 0x0000, 0x0000, 0x7C00, 0x0800, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // z + 0x1800, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1800, // { + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, // | + 0x3000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x3000, // } + 0x0000, 0x0000, 0x0000, 0x7400, 0x4C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +static const unsigned short Font11x18[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // ! + 0x0000, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x0000, 0x1980, 0x1980, 0x1980, 0x1980, 0x7FC0, 0x7FC0, 0x1980, 0x3300, + 0x7FC0, 0x7FC0, 0x3300, 0x3300, 0x3300, 0x3300, 0x0000, 0x0000, 0x0000, // # + 0x0000, 0x1E00, 0x3F00, 0x7580, 0x6580, 0x7400, 0x3C00, 0x1E00, 0x0700, + 0x0580, 0x6580, 0x6580, 0x7580, 0x3F00, 0x1E00, 0x0400, 0x0400, 0x0000, // $ + 0x0000, 0x7000, 0xD800, 0xD840, 0xD8C0, 0xD980, 0x7300, 0x0600, 0x0C00, + 0x1B80, 0x36C0, 0x66C0, 0x46C0, 0x06C0, 0x0380, 0x0000, 0x0000, 0x0000, // % + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x3300, 0x3300, 0x1E00, 0x0C00, 0x3CC0, + 0x66C0, 0x6380, 0x6180, 0x6380, 0x3EC0, 0x1C80, 0x0000, 0x0000, 0x0000, // & + 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x0080, 0x0100, 0x0300, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0300, 0x0100, 0x0080, // ( + 0x2000, 0x1000, 0x1800, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x1800, 0x1000, 0x2000, // ) + 0x0000, 0x0C00, 0x2D00, 0x3F00, 0x1E00, 0x3300, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * + 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0xFFC0, 0xFFC0, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800, // , + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // . + 0x0000, 0x0300, 0x0300, 0x0300, 0x0600, 0x0600, 0x0600, 0x0600, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000, // / + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6D80, 0x6D80, + 0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 0 + 0x0000, 0x0600, 0x0E00, 0x1E00, 0x3600, 0x2600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // 1 + 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, 0x6180, 0x0180, 0x0300, 0x0600, + 0x0C00, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // 2 + 0x0000, 0x1C00, 0x3E00, 0x6300, 0x6300, 0x0300, 0x0E00, 0x0E00, 0x0300, + 0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 3 + 0x0000, 0x0600, 0x0E00, 0x0E00, 0x1E00, 0x1E00, 0x1600, 0x3600, 0x3600, + 0x6600, 0x7F80, 0x7F80, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // 4 + 0x0000, 0x7F00, 0x7F00, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x6380, + 0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 5 + 0x0000, 0x1E00, 0x3F00, 0x3380, 0x6180, 0x6000, 0x6E00, 0x7F00, 0x7380, + 0x6180, 0x6180, 0x6180, 0x3380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 6 + 0x0000, 0x7F80, 0x7F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0600, 0x0C00, + 0x0C00, 0x0C00, 0x0800, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000, // 7 + 0x0000, 0x1E00, 0x3F00, 0x6380, 0x6180, 0x6180, 0x2100, 0x1E00, 0x3F00, + 0x6180, 0x6180, 0x6180, 0x6180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 8 + 0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, + 0x1D80, 0x0180, 0x6180, 0x7300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 9 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800, // ; + 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0380, 0x0E00, 0x3800, 0x6000, + 0x3800, 0x0E00, 0x0380, 0x0080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // < + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7F80, 0x7F80, 0x0000, 0x0000, + 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // = + 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x7000, 0x1C00, 0x0700, 0x0180, + 0x0700, 0x1C00, 0x7000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // > + 0x0000, 0x1F00, 0x3F80, 0x71C0, 0x60C0, 0x00C0, 0x01C0, 0x0380, 0x0700, + 0x0E00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // ? + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x7180, 0x6380, 0x6F80, 0x6D80, 0x6D80, + 0x6F80, 0x6780, 0x6000, 0x3200, 0x3E00, 0x1C00, 0x0000, 0x0000, 0x0000, // @ + 0x0000, 0x0E00, 0x0E00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x3180, 0x3180, + 0x3F80, 0x3F80, 0x3180, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000, // A + 0x0000, 0x7C00, 0x7E00, 0x6300, 0x6300, 0x6300, 0x6300, 0x7E00, 0x7E00, + 0x6300, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, 0x0000, 0x0000, 0x0000, // B + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6000, + 0x6000, 0x6000, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // C + 0x0000, 0x7C00, 0x7F00, 0x6300, 0x6380, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6300, 0x6300, 0x7E00, 0x7C00, 0x0000, 0x0000, 0x0000, // D + 0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, + 0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // E + 0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, + 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, // F + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6380, + 0x6380, 0x6180, 0x6180, 0x3180, 0x3F80, 0x1E00, 0x0000, 0x0000, 0x0000, // G + 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x7F80, 0x7F80, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // H + 0x0000, 0x3F00, 0x3F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3F00, 0x3F00, 0x0000, 0x0000, 0x0000, // I + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // J + 0x0000, 0x60C0, 0x6180, 0x6300, 0x6600, 0x6600, 0x6C00, 0x7800, 0x7C00, + 0x6600, 0x6600, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // K + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, + 0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // L + 0x0000, 0x71C0, 0x71C0, 0x7BC0, 0x7AC0, 0x6AC0, 0x6AC0, 0x6EC0, 0x64C0, + 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000, // M + 0x0000, 0x7180, 0x7180, 0x7980, 0x7980, 0x7980, 0x6D80, 0x6D80, 0x6D80, + 0x6580, 0x6780, 0x6780, 0x6780, 0x6380, 0x6380, 0x0000, 0x0000, 0x0000, // N + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // O + 0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6180, 0x6380, 0x7F00, + 0x7E00, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, // P + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6580, 0x6780, 0x3300, 0x3F80, 0x1E40, 0x0000, 0x0000, 0x0000, // Q + 0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, + 0x6600, 0x6300, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // R + 0x0000, 0x0E00, 0x1F00, 0x3180, 0x3180, 0x3000, 0x3800, 0x1E00, 0x0700, + 0x0380, 0x6180, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // S + 0x0000, 0xFFC0, 0xFFC0, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // T + 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // U + 0x0000, 0x60C0, 0x60C0, 0x60C0, 0x3180, 0x3180, 0x3180, 0x1B00, 0x1B00, + 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x0400, 0x0000, 0x0000, 0x0000, // V + 0x0000, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xCCC0, 0x4C80, 0x4C80, + 0x5E80, 0x5280, 0x5280, 0x7380, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // W + 0x0000, 0xC0C0, 0x6080, 0x6180, 0x3300, 0x3B00, 0x1E00, 0x0C00, 0x0C00, + 0x1E00, 0x1F00, 0x3B00, 0x7180, 0x6180, 0xC0C0, 0x0000, 0x0000, 0x0000, // X + 0x0000, 0xC0C0, 0x6180, 0x6180, 0x3300, 0x3300, 0x1E00, 0x1E00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // Y + 0x0000, 0x3F80, 0x3F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0C00, 0x0C00, + 0x1800, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // Z + 0x0F00, 0x0F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0F00, 0x0F00, // [ + 0x0000, 0x1800, 0x1800, 0x1800, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0300, 0x0300, 0x0300, 0x0000, 0x0000, 0x0000, /* \ */ + 0x1E00, 0x1E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x1E00, 0x1E00, // ] + 0x0000, 0x0C00, 0x0C00, 0x1E00, 0x1200, 0x3300, 0x3300, 0x6180, 0x6180, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFE0, 0x0000, // _ + 0x0000, 0x3800, 0x1800, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F00, 0x3F80, 0x6180, 0x0180, + 0x1F80, 0x3F80, 0x6180, 0x6380, 0x7F80, 0x38C0, 0x0000, 0x0000, 0x0000, // a + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x0000, 0x0000, 0x0000, // b + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, + 0x6000, 0x6000, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // c + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x1D80, 0x3F80, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0000, 0x0000, 0x0000, // d + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, + 0x7F80, 0x7F80, 0x6000, 0x7180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // e + 0x0000, 0x07C0, 0x0FC0, 0x0C00, 0x0C00, 0x7F80, 0x7F80, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // f + 0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x6380, 0x7F00, 0x3E00, // g + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6F00, 0x7F80, 0x7180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // h + 0x0000, 0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // i + 0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x4600, 0x7E00, 0x3C00, // j + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6180, 0x6300, 0x6600, 0x6C00, + 0x7C00, 0x7600, 0x6300, 0x6300, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // k + 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // l + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xFFC0, 0xCEC0, 0xCCC0, + 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0x0000, 0x0000, 0x0000, // m + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6F00, 0x7F80, 0x7180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // n + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // o + 0x0000, 0x0000, 0x0000, 0x0000, 0x6E00, 0x7F00, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x6000, 0x6000, 0x6000, 0x6000, // p + 0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x0180, 0x0180, 0x0180, // q + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6700, 0x3F80, 0x3900, 0x3000, + 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x0000, 0x0000, 0x0000, // r + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F80, 0x6180, 0x6000, + 0x7F00, 0x3F80, 0x0180, 0x6180, 0x7F00, 0x1E00, 0x0000, 0x0000, 0x0000, // s + 0x0000, 0x0000, 0x0800, 0x1800, 0x1800, 0x7F00, 0x7F00, 0x1800, 0x1800, + 0x1800, 0x1800, 0x1800, 0x1800, 0x1F80, 0x0F80, 0x0000, 0x0000, 0x0000, // t + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6380, 0x7F80, 0x3D80, 0x0000, 0x0000, 0x0000, // u + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x60C0, 0x3180, 0x3180, 0x3180, + 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0600, 0x0000, 0x0000, 0x0000, // v + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xDD80, 0xDD80, 0x5500, + 0x5500, 0x5500, 0x7700, 0x7700, 0x2200, 0x2200, 0x0000, 0x0000, 0x0000, // w + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x3300, 0x3300, 0x1E00, + 0x0C00, 0x0C00, 0x1E00, 0x3300, 0x3300, 0x6180, 0x0000, 0x0000, 0x0000, // x + 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x3180, 0x3300, 0x3300, + 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x1C00, 0x7C00, 0x7000, // y + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FC0, 0x7FC0, 0x0180, 0x0300, + 0x0600, 0x0C00, 0x1800, 0x3000, 0x7FC0, 0x7FC0, 0x0000, 0x0000, 0x0000, // z + 0x0380, 0x0780, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0E00, 0x1C00, + 0x1C00, 0x0E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0780, 0x0380, // { + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, // | + 0x3800, 0x3C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0E00, 0x0700, + 0x0700, 0x0E00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3C00, 0x3800, // } + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3880, 0x7F80, + 0x4700, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; +static const unsigned short Font16x26[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [ ] + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, + 0x01C0, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [!] + 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ["] + 0x01CE, 0x03CE, 0x03DE, 0x039E, 0x039C, 0x079C, 0x3FFF, 0x7FFF, 0x0738, 0x0F38, 0x0F78, 0x0F78, 0x0E78, 0xFFFF, + 0xFFFF, 0x1EF0, 0x1CF0, 0x1CE0, 0x3CE0, 0x3DE0, 0x39E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [#] + 0x03FC, 0x0FFE, 0x1FEE, 0x1EE0, 0x1EE0, 0x1EE0, 0x1EE0, 0x1FE0, 0x0FE0, 0x07E0, 0x03F0, 0x01FC, 0x01FE, 0x01FE, + 0x01FE, 0x01FE, 0x01FE, 0x01FE, 0x3DFE, 0x3FFC, 0x0FF0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, // Ascii = [$] + 0x3E03, 0xF707, 0xE78F, 0xE78E, 0xE39E, 0xE3BC, 0xE7B8, 0xE7F8, 0xF7F0, 0x3FE0, 0x01C0, 0x03FF, 0x07FF, 0x07F3, + 0x0FF3, 0x1EF3, 0x3CF3, 0x38F3, 0x78F3, 0xF07F, 0xE03F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [%] + 0x07E0, 0x0FF8, 0x0F78, 0x1F78, 0x1F78, 0x1F78, 0x0F78, 0x0FF0, 0x0FE0, 0x1F80, 0x7FC3, 0xFBC3, 0xF3E7, 0xF1F7, + 0xF0F7, 0xF0FF, 0xF07F, 0xF83E, 0x7C7F, 0x3FFF, 0x1FEF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [&] + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ['] + 0x003F, 0x007C, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x0780, 0x0780, 0x0F80, 0x0F00, 0x0F00, 0x0F00, 0x0F00, 0x0F00, + 0x0F00, 0x0F80, 0x0780, 0x0780, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x007C, 0x003F, 0x000F, 0x0000, // Ascii = [(] + 0x7E00, 0x1F00, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x00F0, 0x00F0, 0x00F8, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, + 0x0078, 0x00F8, 0x00F0, 0x00F0, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x1F00, 0x7E00, 0x7800, 0x0000, // Ascii = [)] + 0x03E0, 0x03C0, 0x01C0, 0x39CE, 0x3FFF, 0x3F7F, 0x0320, 0x0370, 0x07F8, 0x0F78, 0x1F3C, 0x0638, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [*] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0xFFFF, + 0xFFFF, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [+] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x0380, // Ascii = [,] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFE, 0x3FFE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [-] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [.] + 0x000F, 0x000F, 0x001E, 0x001E, 0x003C, 0x003C, 0x0078, 0x0078, 0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, + 0x0780, 0x0780, 0x0F00, 0x0F00, 0x1E00, 0x1E00, 0x3C00, 0x3C00, 0x7800, 0x7800, 0xF000, 0x0000, // Ascii = [/] + 0x07F0, 0x0FF8, 0x1F7C, 0x3E3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, + 0x7C1F, 0x7C1F, 0x3C1E, 0x3E3E, 0x1F7C, 0x0FF8, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [0] + 0x00F0, 0x07F0, 0x3FF0, 0x3FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, + 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [1] + 0x0FE0, 0x3FF8, 0x3C7C, 0x003C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x007C, 0x00F8, 0x01F0, 0x03E0, 0x07C0, + 0x0780, 0x0F00, 0x1E00, 0x3E00, 0x3C00, 0x3FFE, 0x3FFE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [2] + 0x0FF0, 0x1FF8, 0x1C7C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x00F8, 0x0FF0, 0x0FF8, 0x007C, 0x003E, 0x001E, + 0x001E, 0x001E, 0x001E, 0x003E, 0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [3] + 0x0078, 0x00F8, 0x00F8, 0x01F8, 0x03F8, 0x07F8, 0x07F8, 0x0F78, 0x1E78, 0x1E78, 0x3C78, 0x7878, 0x7878, 0xFFFF, + 0xFFFF, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [4] + 0x1FFC, 0x1FFC, 0x1FFC, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FE0, 0x1FF8, 0x00FC, 0x007C, 0x003E, 0x003E, + 0x001E, 0x003E, 0x003E, 0x003C, 0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [5] + 0x01FC, 0x07FE, 0x0F8E, 0x1F00, 0x1E00, 0x3E00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFC, 0x7F3E, 0x7E1F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3E0F, 0x1E1F, 0x1F3E, 0x0FFC, 0x03F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [6] + 0x3FFF, 0x3FFF, 0x3FFF, 0x000F, 0x001E, 0x001E, 0x003C, 0x0038, 0x0078, 0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, + 0x03C0, 0x0780, 0x0F80, 0x0F80, 0x0F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [7] + 0x07F8, 0x0FFC, 0x1F3E, 0x1E1E, 0x3E1E, 0x3E1E, 0x1E1E, 0x1F3C, 0x0FF8, 0x07F0, 0x0FF8, 0x1EFC, 0x3E3E, 0x3C1F, + 0x7C1F, 0x7C0F, 0x7C0F, 0x3C1F, 0x3F3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [8] + 0x07F0, 0x0FF8, 0x1E7C, 0x3C3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x3C1F, 0x3E3F, 0x1FFF, 0x07EF, 0x001F, + 0x001E, 0x001E, 0x003E, 0x003C, 0x38F8, 0x3FF0, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [9] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [:] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x0380, // Ascii = [;] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x000F, 0x003F, 0x00FC, 0x03F0, 0x0FC0, 0x3F00, 0xFE00, + 0x3F00, 0x0FC0, 0x03F0, 0x00FC, 0x003F, 0x000F, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [<] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [=] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE000, 0xF800, 0x7E00, 0x1F80, 0x07E0, 0x01F8, 0x007E, 0x001F, + 0x007E, 0x01F8, 0x07E0, 0x1F80, 0x7E00, 0xF800, 0xE000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [>] + 0x1FF0, 0x3FFC, 0x383E, 0x381F, 0x381F, 0x001E, 0x001E, 0x003C, 0x0078, 0x00F0, 0x01E0, 0x03C0, 0x03C0, 0x07C0, + 0x07C0, 0x0000, 0x0000, 0x0000, 0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [?] + 0x03F8, 0x0FFE, 0x1F1E, 0x3E0F, 0x3C7F, 0x78FF, 0x79EF, 0x73C7, 0xF3C7, 0xF38F, 0xF38F, 0xF38F, 0xF39F, 0xF39F, + 0x73FF, 0x7BFF, 0x79F7, 0x3C00, 0x1F1C, 0x0FFC, 0x03F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [@] + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x07F0, 0x0F78, 0x0F78, 0x0E7C, 0x1E3C, 0x1E3C, 0x3C3E, + 0x3FFE, 0x3FFF, 0x781F, 0x780F, 0xF00F, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [A] + 0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FFC, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7C, 0x3FF0, 0x3FF8, 0x3C7E, + 0x3C1F, 0x3C1F, 0x3C0F, 0x3C0F, 0x3C1F, 0x3FFE, 0x3FF8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [B] + 0x0000, 0x0000, 0x0000, 0x01FF, 0x07FF, 0x1F87, 0x3E00, 0x3C00, 0x7C00, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, + 0x7C00, 0x7C00, 0x3E00, 0x3F00, 0x1F83, 0x07FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [C] + 0x0000, 0x0000, 0x0000, 0x7FF0, 0x7FFC, 0x787E, 0x781F, 0x781F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, + 0x780F, 0x780F, 0x781F, 0x781E, 0x787E, 0x7FF8, 0x7FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [D] + 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFE, 0x3FFE, 0x3E00, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [E] + 0x0000, 0x0000, 0x0000, 0x1FFF, 0x1FFF, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FFF, 0x1FFF, 0x1E00, + 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [F] + 0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x7C00, 0x7C00, 0x7800, 0xF800, 0xF800, 0xF87F, 0xF87F, + 0x780F, 0x7C0F, 0x7C0F, 0x3E0F, 0x1F8F, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [G] + 0x0000, 0x0000, 0x0000, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7FFF, 0x7FFF, 0x7C1F, + 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [H] + 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [I] + 0x0000, 0x0000, 0x0000, 0x1FFC, 0x1FFC, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, + 0x007C, 0x007C, 0x0078, 0x0078, 0x38F8, 0x3FF0, 0x3FC0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [J] + 0x0000, 0x0000, 0x0000, 0x3C1F, 0x3C1E, 0x3C3C, 0x3C78, 0x3CF0, 0x3DE0, 0x3FE0, 0x3FC0, 0x3F80, 0x3FC0, 0x3FE0, + 0x3DF0, 0x3CF0, 0x3C78, 0x3C7C, 0x3C3E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [K] + 0x0000, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [L] + 0x0000, 0x0000, 0x0000, 0xF81F, 0xFC1F, 0xFC1F, 0xFE3F, 0xFE3F, 0xFE3F, 0xFF7F, 0xFF77, 0xFF77, 0xF7F7, 0xF7E7, + 0xF3E7, 0xF3E7, 0xF3C7, 0xF007, 0xF007, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [M] + 0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7E0F, 0x7F0F, 0x7F0F, 0x7F8F, 0x7F8F, 0x7FCF, 0x7BEF, 0x79EF, 0x79FF, + 0x78FF, 0x78FF, 0x787F, 0x783F, 0x783F, 0x781F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [N] + 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, + 0xF80F, 0x780F, 0x780F, 0x7C1F, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [O] + 0x0000, 0x0000, 0x0000, 0x3FFC, 0x3FFF, 0x3E1F, 0x3E0F, 0x3E0F, 0x3E0F, 0x3E0F, 0x3E1F, 0x3E3F, 0x3FFC, 0x3FF0, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [P] + 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, + 0xF80F, 0x780F, 0x780F, 0x7C1F, 0x3E3E, 0x1FFC, 0x07F8, 0x007C, 0x003F, 0x000F, 0x0003, 0x0000, // Ascii = [Q] + 0x0000, 0x0000, 0x0000, 0x3FF0, 0x3FFC, 0x3C7E, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C3C, 0x3CFC, 0x3FF0, 0x3FE0, + 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, 0x3C1E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [R] + 0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x3E0E, 0x3C00, 0x3C00, 0x3C00, 0x3E00, 0x1FC0, 0x0FF8, 0x03FE, 0x007F, + 0x001F, 0x000F, 0x000F, 0x201F, 0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [S] + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [T] + 0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, + 0x7C0F, 0x7C0F, 0x3C1E, 0x3C1E, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [U] + 0x0000, 0x0000, 0x0000, 0xF007, 0xF007, 0xF807, 0x780F, 0x7C0F, 0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1F3C, 0x1F78, + 0x0F78, 0x0FF8, 0x07F0, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [V] + 0x0000, 0x0000, 0x0000, 0xE003, 0xF003, 0xF003, 0xF007, 0xF3E7, 0xF3E7, 0xF3E7, 0x73E7, 0x7BF7, 0x7FF7, 0x7FFF, + 0x7F7F, 0x7F7F, 0x7F7E, 0x3F7E, 0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [W] + 0x0000, 0x0000, 0x0000, 0xF807, 0x7C0F, 0x3E1E, 0x3E3E, 0x1F3C, 0x0FF8, 0x07F0, 0x07E0, 0x03E0, 0x03E0, 0x07F0, + 0x0FF8, 0x0F7C, 0x1E7C, 0x3C3E, 0x781F, 0x780F, 0xF00F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [X] + 0x0000, 0x0000, 0x0000, 0xF807, 0x7807, 0x7C0F, 0x3C1E, 0x3E1E, 0x1F3C, 0x0F78, 0x0FF8, 0x07F0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Y] + 0x0000, 0x0000, 0x0000, 0x7FFF, 0x7FFF, 0x000F, 0x001F, 0x003E, 0x007C, 0x00F8, 0x00F0, 0x01E0, 0x03E0, 0x07C0, + 0x0F80, 0x0F00, 0x1E00, 0x3E00, 0x7C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Z] + 0x07FF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, + 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x07FF, 0x07FF, 0x0000, // Ascii = [[] + 0x7800, 0x7800, 0x3C00, 0x3C00, 0x1E00, 0x1E00, 0x0F00, 0x0F00, 0x0780, 0x0780, 0x03C0, 0x03C0, 0x01E0, 0x01E0, + 0x00F0, 0x00F0, 0x0078, 0x0078, 0x003C, 0x003C, 0x001E, 0x001E, 0x000F, 0x000F, 0x0007, 0x0000, // Ascii = [\] + 0x7FF0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, + 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x7FF0, 0x7FF0, 0x0000, // Ascii = []] + 0x00C0, 0x01C0, 0x01C0, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x0778, 0x0F78, 0x0F38, 0x1E3C, 0x1E3C, 0x3C1E, 0x3C1E, + 0x380F, 0x780F, 0x7807, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [^] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, // Ascii = [_] + 0x00F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [`] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0FF8, 0x3FFC, 0x3C7C, 0x003E, 0x003E, 0x003E, 0x07FE, 0x1FFE, + 0x3E3E, 0x7C3E, 0x783E, 0x7C3E, 0x7C7E, 0x3FFF, 0x1FCF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [a] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFE, 0x3F3E, 0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3C1F, 0x3C1E, 0x3F3E, 0x3FFC, 0x3BF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [b] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x3E00, 0x3C00, 0x7C00, 0x7C00, + 0x7C00, 0x3C00, 0x3E00, 0x3E00, 0x1F87, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [c] + 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x07FF, 0x1FFF, 0x3E3F, 0x3C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x781F, + 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, 0x3E7F, 0x1FFF, 0x0FDF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [d] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03F8, 0x0FFC, 0x1F3E, 0x3E1E, 0x3C1F, 0x7C1F, 0x7FFF, 0x7FFF, + 0x7C00, 0x7C00, 0x3C00, 0x3E00, 0x1F07, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [e] + 0x01FF, 0x03E1, 0x03C0, 0x07C0, 0x07C0, 0x07C0, 0x7FFF, 0x7FFF, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, + 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [f] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EF, 0x1FFF, 0x3E7F, 0x3C1F, 0x7C1F, 0x7C1F, 0x781F, 0x781F, + 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, 0x3E7F, 0x1FFF, 0x0FDF, 0x001E, 0x001E, 0x001E, 0x387C, 0x3FF8, // Ascii = [g] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DFC, 0x3FFE, 0x3F9E, 0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, + 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [h] + 0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FE0, 0x7FE0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, + 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [i] + 0x00F8, 0x00F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FF8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, + 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F0, 0x71F0, 0x7FE0, // Ascii = [j] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C1F, 0x3C3E, 0x3C7C, 0x3CF8, 0x3DF0, 0x3DE0, 0x3FC0, 0x3FC0, + 0x3FE0, 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [k] + 0x7FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, + 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [l] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF79E, 0xFFFF, 0xFFFF, 0xFFFF, 0xFBE7, 0xF9E7, 0xF1C7, 0xF1C7, + 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [m] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DFC, 0x3FFE, 0x3F9E, 0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, + 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [n] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x3C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, + 0x780F, 0x780F, 0x7C1F, 0x3C1F, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [o] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DF8, 0x3FFE, 0x3F3E, 0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3C1F, 0x3E1E, 0x3F3E, 0x3FFC, 0x3FF8, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, // Ascii = [p] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EE, 0x1FFE, 0x3E7E, 0x3C1E, 0x7C1E, 0x781E, 0x781E, 0x781E, + 0x781E, 0x781E, 0x7C1E, 0x7C3E, 0x3E7E, 0x1FFE, 0x0FDE, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, // Ascii = [q] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F7F, 0x1FFF, 0x1FE7, 0x1FC7, 0x1F87, 0x1F00, 0x1F00, 0x1F00, + 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [r] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x1E0E, 0x3E00, 0x3E00, 0x3F00, 0x1FE0, 0x07FC, + 0x00FE, 0x003E, 0x001E, 0x001E, 0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [s] + 0x0000, 0x0000, 0x0000, 0x0780, 0x0780, 0x0780, 0x7FFF, 0x7FFF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, + 0x0780, 0x0780, 0x0780, 0x0780, 0x07C0, 0x03FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [t] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, + 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7E, 0x3EFE, 0x1FFE, 0x0FDE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [u] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF007, 0x780F, 0x780F, 0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1E3C, + 0x0F78, 0x0F78, 0x0FF0, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [v] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF003, 0xF1E3, 0xF3E3, 0xF3E7, 0xF3F7, 0xF3F7, 0x7FF7, 0x7F77, + 0x7F7F, 0x7F7F, 0x7F7F, 0x3E3E, 0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [w] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7C0F, 0x3E1E, 0x3E3C, 0x1F3C, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, + 0x07F0, 0x07F8, 0x0FF8, 0x1E7C, 0x3E3E, 0x3C1F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [x] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF807, 0x780F, 0x7C0F, 0x3C1E, 0x3C1E, 0x1E3C, 0x1E3C, 0x1F3C, + 0x0F78, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x0780, 0x0F80, 0x7F00, // Ascii = [y] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x001F, 0x003E, 0x007C, 0x00F8, 0x01F0, 0x03E0, + 0x07C0, 0x0F80, 0x1F00, 0x1E00, 0x3C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [z] + 0x01FE, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x3F80, 0x3F80, 0x03C0, + 0x01C0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x03E0, 0x01FE, 0x007E, 0x0000, // Ascii = [{] + 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, + 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, // Ascii = [|] + 0x3FC0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x03C0, 0x01C0, 0x01E0, 0x00FE, 0x00FE, 0x01E0, + 0x01C0, 0x03C0, 0x03C0, 0x01C0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x03E0, 0x3FC0, 0x3F00, 0x0000, // Ascii = [}] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3F07, 0x7FC7, 0x73E7, + 0xF1FF, 0xF07E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [~] +}; +static const unsigned short Font6x8[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, 0x2000, 0x0000, // ! + 0x5000, 0x5000, 0x5000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x5000, 0x5000, 0xf800, 0x5000, 0xf800, 0x5000, 0x5000, 0x0000, // # + 0x2000, 0x7800, 0xa000, 0x7000, 0x2800, 0xf000, 0x2000, 0x0000, // $ + 0xc000, 0xc800, 0x1000, 0x2000, 0x4000, 0x9800, 0x1800, 0x0000, // % + 0x4000, 0xa000, 0xa000, 0x4000, 0xa800, 0x9000, 0x6800, 0x0000, // & + 0x3000, 0x3000, 0x2000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x1000, 0x2000, 0x4000, 0x4000, 0x4000, 0x2000, 0x1000, 0x0000, // ( + 0x4000, 0x2000, 0x1000, 0x1000, 0x1000, 0x2000, 0x4000, 0x0000, // ) + 0x2000, 0xa800, 0x7000, 0xf800, 0x7000, 0xa800, 0x2000, 0x0000, // * + 0x0000, 0x2000, 0x2000, 0xf800, 0x2000, 0x2000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3000, 0x2000, 0x0000, // , + 0x0000, 0x0000, 0x0000, 0xf800, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3000, 0x0000, // . + 0x0000, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x0000, 0x0000, // / + 0x7000, 0x8800, 0x9800, 0xa800, 0xc800, 0x8800, 0x7000, 0x0000, // 0 + 0x2000, 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // 1 + 0x7000, 0x8800, 0x0800, 0x7000, 0x8000, 0x8000, 0xf800, 0x0000, // 2 + 0xf800, 0x0800, 0x1000, 0x3000, 0x0800, 0x8800, 0x7000, 0x0000, // 3 + 0x1000, 0x3000, 0x5000, 0x9000, 0xf800, 0x1000, 0x1000, 0x0000, // 4 + 0xf800, 0x8000, 0xf000, 0x0800, 0x0800, 0x8800, 0x7000, 0x0000, // 5 + 0x3800, 0x4000, 0x8000, 0xf000, 0x8800, 0x8800, 0x7000, 0x0000, // 6 + 0xf800, 0x0800, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x0000, // 7 + 0x7000, 0x8800, 0x8800, 0x7000, 0x8800, 0x8800, 0x7000, 0x0000, // 8 + 0x7000, 0x8800, 0x8800, 0x7800, 0x0800, 0x1000, 0xe000, 0x0000, // 9 + 0x0000, 0x0000, 0x2000, 0x0000, 0x2000, 0x0000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x2000, 0x0000, 0x2000, 0x2000, 0x4000, 0x0000, // ; + 0x0800, 0x1000, 0x2000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0000, // < + 0x0000, 0x0000, 0xf800, 0x0000, 0xf800, 0x0000, 0x0000, 0x0000, // = + 0x4000, 0x2000, 0x1000, 0x0800, 0x1000, 0x2000, 0x4000, 0x0000, // > + 0x7000, 0x8800, 0x0800, 0x3000, 0x2000, 0x0000, 0x2000, 0x0000, // ? + 0x7000, 0x8800, 0xa800, 0xb800, 0xb000, 0x8000, 0x7800, 0x0000, // @ + 0x2000, 0x5000, 0x8800, 0x8800, 0xf800, 0x8800, 0x8800, 0x0000, // A + 0xf000, 0x8800, 0x8800, 0xf000, 0x8800, 0x8800, 0xf000, 0x0000, // B + 0x7000, 0x8800, 0x8000, 0x8000, 0x8000, 0x8800, 0x7000, 0x0000, // C + 0xf000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0xf000, 0x0000, // D + 0xf800, 0x8000, 0x8000, 0xf000, 0x8000, 0x8000, 0xf800, 0x0000, // E + 0xf800, 0x8000, 0x8000, 0xf000, 0x8000, 0x8000, 0x8000, 0x0000, // F + 0x7800, 0x8800, 0x8000, 0x8000, 0x9800, 0x8800, 0x7800, 0x0000, // G + 0x8800, 0x8800, 0x8800, 0xf800, 0x8800, 0x8800, 0x8800, 0x0000, // H + 0x7000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // I + 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x9000, 0x6000, 0x0000, // J + 0x8800, 0x9000, 0xa000, 0xc000, 0xa000, 0x9000, 0x8800, 0x0000, // K + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0xf800, 0x0000, // L + 0x8800, 0xd800, 0xa800, 0xa800, 0xa800, 0x8800, 0x8800, 0x0000, // M + 0x8800, 0x8800, 0xc800, 0xa800, 0x9800, 0x8800, 0x8800, 0x0000, // N + 0x7000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // O + 0xf000, 0x8800, 0x8800, 0xf000, 0x8000, 0x8000, 0x8000, 0x0000, // P + 0x7000, 0x8800, 0x8800, 0x8800, 0xa800, 0x9000, 0x6800, 0x0000, // Q + 0xf000, 0x8800, 0x8800, 0xf000, 0xa000, 0x9000, 0x8800, 0x0000, // R + 0x7000, 0x8800, 0x8000, 0x7000, 0x0800, 0x8800, 0x7000, 0x0000, // S + 0xf800, 0xa800, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, // T + 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // U + 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x5000, 0x2000, 0x0000, // V + 0x8800, 0x8800, 0x8800, 0xa800, 0xa800, 0xa800, 0x5000, 0x0000, // W + 0x8800, 0x8800, 0x5000, 0x2000, 0x5000, 0x8800, 0x8800, 0x0000, // X + 0x8800, 0x8800, 0x5000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, // Y + 0xf800, 0x0800, 0x1000, 0x7000, 0x4000, 0x8000, 0xf800, 0x0000, // Z + 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7800, 0x0000, // [ + 0x0000, 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0000, 0x0000, /* \ */ + 0x7800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x7800, 0x0000, // ] + 0x2000, 0x5000, 0x8800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf800, 0x0000, // _ + 0x6000, 0x6000, 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x6000, 0x1000, 0x7000, 0x9000, 0x7800, 0x0000, // a + 0x8000, 0x8000, 0xb000, 0xc800, 0x8800, 0xc800, 0xb000, 0x0000, // b + 0x0000, 0x0000, 0x7000, 0x8800, 0x8000, 0x8800, 0x7000, 0x0000, // c + 0x0800, 0x0800, 0x6800, 0x9800, 0x8800, 0x9800, 0x6800, 0x0000, // d + 0x0000, 0x0000, 0x7000, 0x8800, 0xf800, 0x8000, 0x7000, 0x0000, // e + 0x1000, 0x2800, 0x2000, 0x7000, 0x2000, 0x2000, 0x2000, 0x0000, // f + 0x0000, 0x0000, 0x7000, 0x9800, 0x9800, 0x6800, 0x0800, 0x0000, // g + 0x8000, 0x8000, 0xb000, 0xc800, 0x8800, 0x8800, 0x8800, 0x0000, // h + 0x2000, 0x0000, 0x6000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // i + 0x1000, 0x0000, 0x1000, 0x1000, 0x1000, 0x9000, 0x6000, 0x0000, // j + 0x8000, 0x8000, 0x9000, 0xa000, 0xc000, 0xa000, 0x9000, 0x0000, // k + 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // l + 0x0000, 0x0000, 0xd000, 0xa800, 0xa800, 0xa800, 0xa800, 0x0000, // m + 0x0000, 0x0000, 0xb000, 0xc800, 0x8800, 0x8800, 0x8800, 0x0000, // n + 0x0000, 0x0000, 0x7000, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // o + 0x0000, 0x0000, 0xb000, 0xc800, 0xc800, 0xb000, 0x8000, 0x0000, // p + 0x0000, 0x0000, 0x6800, 0x9800, 0x9800, 0x6800, 0x0800, 0x0000, // q + 0x0000, 0x0000, 0xb000, 0xc800, 0x8000, 0x8000, 0x8000, 0x0000, // r + 0x0000, 0x0000, 0x7800, 0x8000, 0x7000, 0x0800, 0xf000, 0x0000, // s + 0x2000, 0x2000, 0xf800, 0x2000, 0x2000, 0x2800, 0x1000, 0x0000, // t + 0x0000, 0x0000, 0x8800, 0x8800, 0x8800, 0x9800, 0x6800, 0x0000, // u + 0x0000, 0x0000, 0x8800, 0x8800, 0x8800, 0x5000, 0x2000, 0x0000, // v + 0x0000, 0x0000, 0x8800, 0x8800, 0xa800, 0xa800, 0x5000, 0x0000, // w + 0x0000, 0x0000, 0x8800, 0x5000, 0x2000, 0x5000, 0x8800, 0x0000, // x + 0x0000, 0x0000, 0x8800, 0x8800, 0x7800, 0x0800, 0x8800, 0x0000, // y + 0x0000, 0x0000, 0xf800, 0x1000, 0x2000, 0x4000, 0xf800, 0x0000, // z + 0x1000, 0x2000, 0x2000, 0x4000, 0x2000, 0x2000, 0x1000, 0x0000, // { + 0x2000, 0x2000, 0x2000, 0x0000, 0x2000, 0x2000, 0x2000, 0x0000, // | + 0x4000, 0x2000, 0x2000, 0x1000, 0x2000, 0x2000, 0x4000, 0x0000, // } + 0x4000, 0xa800, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +FontDef Font_7x10 = {7, 10, Font7x10}; +FontDef Font_6x8 = {6, 8, Font6x8}; +FontDef Font_11x18 = {11, 18, Font11x18}; +FontDef Font_16x26 = {16, 26, Font16x26}; \ No newline at end of file diff --git a/src/vendor/test/oled/ssd1306_fonts.h b/src/vendor/test/oled/ssd1306_fonts.h new file mode 100644 index 0000000000000000000000000000000000000000..21afb48aa124f6e4579b1520082c9d3571f381db --- /dev/null +++ b/src/vendor/test/oled/ssd1306_fonts.h @@ -0,0 +1,58 @@ +/* + MIT License + + Copyright (c) 2018, Alexey Dynda + + 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. +*/ +/** + * @file ssd1306_fonts.h Fonts for monochrome/rgb oled display + */ + +#ifndef SSD1306_FONTS_H +#define SSD1306_FONTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup LCD_FONTS FONTS: Supported LCD fonts + * @{ + */ + +extern const unsigned char g_f6X8[][6]; +extern const unsigned char g_f8X16[]; + +typedef struct { + const unsigned char FontWidth; /*!< Font width in pixels */ + unsigned char FontHeight; /*!< Font height in pixels */ + const unsigned short *data; /*!< Pointer to data font data array */ +} FontDef; + +extern FontDef Font_7x10; +extern FontDef Font_6x8; +extern FontDef Font_11x18; +extern FontDef Font_16x26; + +#ifdef __cplusplus +} +#endif + +#endif // SSD1306_FONTS_H \ No newline at end of file diff --git a/src/vendor/test/radar_led/CMakeLists.txt b/src/vendor/test/radar_led/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1e52036834ff3fde6f6fa7df61f25c912536dbd7 --- /dev/null +++ b/src/vendor/test/radar_led/CMakeLists.txt @@ -0,0 +1,11 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +if(DEFINED CONFIG_SAMPLE_SUPPORT_RADAR_STA) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/radar_sta_sample/radar_sta_sample.c" PARENT_SCOPE) + set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/../../include/middleware/services/radar/radar_service.h" PARENT_SCOPE) +elseif(DEFINED CONFIG_SAMPLE_SUPPORT_RADAR_SOFTAP) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/radar_softap_sample/radar_softap_sample.c" PARENT_SCOPE) + set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/../../include/middleware/services/radar/radar_service.h" PARENT_SCOPE) +endif() \ No newline at end of file diff --git a/src/vendor/test/radar_led/Kconfig b/src/vendor/test/radar_led/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..9848582f8ea534375d47afa314f8f55e49f53a07 --- /dev/null +++ b/src/vendor/test/radar_led/Kconfig @@ -0,0 +1,19 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +config SAMPLE_SUPPORT_RADAR_STA + bool + prompt "Support RADAR_STA Sample." + default n + depends on SAMPLE_SUPPORT_RADAR_LED + help + This option means support RADAR_STA Sample. + +config SAMPLE_SUPPORT_RADAR_SOFTAP + bool + prompt "Support RADAR_SOFTAP Sample." + default n + depends on SAMPLE_SUPPORT_RADAR_LED + help + This option means support RADAR_SOFTAP Sample. \ No newline at end of file diff --git a/src/vendor/test/radar_led/README.md b/src/vendor/test/radar_led/README.md new file mode 100644 index 0000000000000000000000000000000000000000..18f46a2cb50d2be8c4ac988ab3ae29b480869004 --- /dev/null +++ b/src/vendor/test/radar_led/README.md @@ -0,0 +1,127 @@ +# radar_led + +## 1.1 介绍 + +**功能介绍:** 雷达运动感知,检测物体在6M以内是否有运动。如果有则亮绿灯,如果检测物体在0M-1M以内,则亮红灯,如果检测物体在1M-2M以内,则亮绿灯。 + +**硬件概述:** 核心板、交通灯板。通过板端丝印可以看出交通灯板的蜂鸣器BEEP与底板的A9相连,底板左边A9对应核心板GPIO 9。硬件搭建要求如图所示: + + 参考[交通灯板原理图](../../../docs/hardwar/HiSpark_WiFi_IoT_SSL_VER.A.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf) + + image-20240415144302434 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 检测物体在6M以内是否有运动。如果有则亮绿灯,如果检测物体在0M-1M以内,则亮红灯,如果检测物体在1M-2M以内,则亮绿灯。 + +## 1.4 接口介绍 + +### 1.4.1 wifi_softap_enable() + +| **定义:** | errcode_t wifi_softap_enable(const softap_config_stru *config); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 开启SoftAP | +| **参数:** | config:SoftAp的配置 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\middleware\services\wifi\wifi_hotspot.h | + +### 1.4.2 netifapi_netif_set_addr() + +| **定义:** | err_t netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置网络接口的IP地址 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | open_source\lwip\lwip_v2.1.3\src\include\lwip\netifapi.h | + +### 1.4.3 netifapi_dhcps_start() + +| **定义:** | err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 启动dhcp服务 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | open_source\lwip\lwip_v2.1.3\src\include\lwip\netifapi.h | + +### 1.4.4 uapi_radar_register_result_cb() + +| **定义:** | errcode_t uapi_radar_register_result_cb(radar_result_cb_t cb); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 雷达结果回调注册函数 | +| **参数:** | cb:回调函数 | +| **返回值:** | 执行结果错误码 | +| **依赖:** | include\middleware\services\radar\radar_service.h | + +### 1.4.5 uapi_radar_set_status() + +| **定义:** | errcode_t uapi_radar_set_status(uint8_t sts); | +| ------------ | ------------------------------------------------- | +| **功能:** | 设置雷达状态 | +| **参数:** | sts:雷达状态 | +| **返回值:** | 执行结果错误码 | +| **依赖:** | include\middleware\services\radar\radar_service.h | + +### 1.4.6 uapi_radar_set_delay_time() + +| **定义:** | errcode_t uapi_radar_set_delay_time(uint16_t time); | +| ------------ | --------------------------------------------------- | +| **功能:** | 设置退出延迟时间 | +| **参数:** | time:退出延迟时间 | +| **返回值:** | 执行结果错误码 | +| **依赖:** | include\middleware\services\radar\radar_service.h | + +## 1.5 具体实现 + + 步骤一:启动WiFi STA或者WiFi AP模式。 + + 步骤二:启动成功后,初始化雷达参数,并注册雷达结果回调函数。 + + 步骤三:设置雷达状态,并设备雷达退出延迟时间。 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”radar_led“。 + + ![image-20240402193714218](../../../docs/pic/wifidemo/image-20240402193714218.png) + +- 步骤二:将open_cfbb\vendor\hihspark\radar_led文件里面内容拷贝到**步骤一创建的Sample文件夹中”radar_led“**下。 + + ![image-20240411175335233](../../../docs/pic/radar_led/image-20240411175335233.png) + +- 步骤三:将open_cfbb\src\application\samples\CMakeLists.txt新增如下内容。 + + ![image-20240411175210538](../../../docs/pic/radar_led/image-20240411175210538.png) + +- 步骤四:将open_cfbb\src\application\samples\Kconfig新增如下内容。 + + ![image-20240411175237268](../../../docs/pic/radar_led/image-20240411175237268.png) + +- 步骤五:点击如下图标,选择KConfig,具体选择路径“Application/Enable Sample ”,如果选择编译RADAR_SOFTAP,在弹出框中选择“support RADAR_SOFTAP Sample”,点击Save,关闭弹窗;如果选择编译RADAR_STA ,在弹出框中选择“support RADAR_STA Sample”,点击Save,关闭弹窗。(需要准备两块开发板,选择不同的编译选项,烧录不同的镜像) + + ![image-20240411175315784](../../../docs/pic/radar_led/image-20240411175315784.png) + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七:检测到物体在6M以内正在移动,亮绿灯,检测到物体在0M-1M以内运动,亮红灯,检测到物体在1M-2M,亮黄灯。 diff --git a/src/vendor/test/radar_led/radar_softap_sample/radar_softap_sample.c b/src/vendor/test/radar_led/radar_softap_sample/radar_softap_sample.c new file mode 100644 index 0000000000000000000000000000000000000000..dbce4ec3a9ed63836469ec6ae75ad1dc44b321cf --- /dev/null +++ b/src/vendor/test/radar_led/radar_softap_sample/radar_softap_sample.c @@ -0,0 +1,252 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved. \n + * + * Description: Application core main function for standard \n + * Author: @CompanyNameTag \n + * History: \n + * 2022-07-27, Create file. \n + */ + +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "td_base.h" +#include "td_type.h" +#include "stdlib.h" +#include "uart.h" +#include "soc_osal.h" +#include "radar_service.h" +#include "gpio.h" +#include "pinctrl.h" +#include "app_init.h" + +#define WIFI_IFNAME_MAX_SIZE 16 +#define WIFI_MAX_KEY_LEN 65 +#define WIFI_MAX_SSID_LEN 33 +#define WIFI_INIT_WAIT_TIME 5000 // 5s +#define WIFI_START_SOFTAP_DELAY 1000 // 1s +#define WIFI_IP_1 192 +#define WIFI_IP_2 168 +#define WIFI_IP_3 130 +#define WIFI_IP_4 1 +#define WIFI_IP_5 255 + +#define WIFI_CHANNEL_NUM 12 +#define WIFI_SECURITY_TYPE 3 + +#define WIFI_BECAON_INTERVAL 100 +#define WIFI_DTIM_PERIOD 2 +#define WIFI_GROUP_REKEY 86400 +#define WIFI_PROTOCOL_MODE 4 +#define WIFI_HIDDEN_SSID_FLAG 1 + +#define RADAR_STATUS_QUERY_DELAY 1000 // 10s + +#define RADAR_DEFAULT_LOOP 8 +#define RADAR_DEFAULT_PERIOD 5000 +#define RADAR_DEFAULT_DBG_TYPE 1 +#define RADAR_DEFAULT_WAVE 2 + +#define RADAR_API_NO_HUMAN 0 +#define RADAR_API_RANGE_CLOSE 50 +#define RADAR_API_RANGE_NEAR 100 +#define RADAR_API_RANGE_MEDIUM 200 +#define RADAR_API_RANGE_FAR 600 + +#define CONFIG_RED_LED_PIN 7 +#define CONFIG_GREEN_LED_PIN 11 +#define CONFIG_YELLOW_LED_PIN 10 + +#define RADAR_TASK_PRIO 24 +#define RADAR_TASK_STACK_SIZE 0x1000 + +static void gpio_set_value(pin_t pin) +{ + uapi_pin_set_mode(pin, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(pin, GPIO_DIRECTION_OUTPUT); +} + +static void radar_led_init(void) +{ + // 1. 初始化所有GPIO并设置GPIO的类型 + uapi_gpio_init(); + gpio_set_value(CONFIG_RED_LED_PIN); + gpio_set_value(CONFIG_GREEN_LED_PIN); + gpio_set_value(CONFIG_YELLOW_LED_PIN); +} + +static void radar_switch_green_on_off(bool onoff) +{ + if (onoff) { + uapi_gpio_set_val(CONFIG_GREEN_LED_PIN, GPIO_LEVEL_LOW); + } else { + uapi_gpio_set_val(CONFIG_GREEN_LED_PIN, GPIO_LEVEL_HIGH); + } +} + +static void radar_switch_yellow_on_off(bool onoff) +{ + if (onoff) { + uapi_gpio_set_val(CONFIG_YELLOW_LED_PIN, GPIO_LEVEL_LOW); + } else { + uapi_gpio_set_val(CONFIG_YELLOW_LED_PIN, GPIO_LEVEL_HIGH); + } +} + +static void radar_switch_red_on_off(bool onoff) +{ + if (onoff) { + uapi_gpio_set_val(CONFIG_RED_LED_PIN, GPIO_LEVEL_LOW); + } else { + uapi_gpio_set_val(CONFIG_RED_LED_PIN, GPIO_LEVEL_HIGH); + } +} + +static void radar_ctrl_led(radar_result_t *res) +{ + if (res->is_human_presence) { + radar_switch_green_on_off(true); + } else { + radar_switch_green_on_off(false); + } + if (res->lower_boundary == 0 && res->upper_boundary == RADAR_API_RANGE_NEAR) { + printf("R 1 meters\r\n"); + radar_switch_red_on_off(true); + radar_switch_yellow_on_off(true); + } else if ((res->lower_boundary == RADAR_API_RANGE_NEAR && res->upper_boundary == RADAR_API_RANGE_MEDIUM)) { + printf("R 2 meters\r\n"); + radar_switch_red_on_off(false); + radar_switch_yellow_on_off(true); + } else { + printf("R xxxx meters\r\n"); + radar_switch_red_on_off(false); + radar_switch_yellow_on_off(false); + } +} + +/***************************************************************************** + Radar SoftAP+Socket sample用例 +*****************************************************************************/ +static errcode_t radar_start_softap(void) +{ + /* SoftAp接口的信息 */ + char ssid[WIFI_MAX_SSID_LEN] = "my_softAP"; + char pre_shared_key[WIFI_MAX_KEY_LEN] = "123456789"; + softap_config_stru hapd_conf = {0}; + softap_config_advance_stru config = {0}; + char ifname[WIFI_IFNAME_MAX_SIZE + 1] = "ap0"; /* 创建的SoftAp接口名 */ + struct netif *netif_p = TD_NULL; + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + IP4_ADDR(&st_ipaddr, WIFI_IP_1, WIFI_IP_2, WIFI_IP_3, WIFI_IP_4); /* IP地址设置:192.168.43.1 */ + IP4_ADDR(&st_netmask, WIFI_IP_5, WIFI_IP_5, WIFI_IP_5, 0); /* 子网掩码设置:255.255.255.0 */ + IP4_ADDR(&st_gw, WIFI_IP_1, WIFI_IP_2, WIFI_IP_3, WIFI_IP_4); /* 网关地址设置:192.168.43.2 */ + + printf("SoftAP try enable.\r\n"); + + (void)memcpy_s(hapd_conf.ssid, sizeof(hapd_conf.ssid), ssid, sizeof(ssid)); + (void)memcpy_s(hapd_conf.pre_shared_key, WIFI_MAX_KEY_LEN, pre_shared_key, WIFI_MAX_KEY_LEN); + hapd_conf.security_type = WIFI_SECURITY_TYPE; /* 3: 加密方式设置为WPA_WPA2_PSK */ + hapd_conf.channel_num = WIFI_CHANNEL_NUM; /* 12:工作信道设置为12信道 */ + hapd_conf.wifi_psk_type = 0; + + /* 配置SoftAp网络参数 */ + config.beacon_interval = WIFI_BECAON_INTERVAL; /* 100:Beacon周期设置为100ms */ + config.dtim_period = WIFI_DTIM_PERIOD; /* 2:DTIM周期设置为2 */ + config.gi = 0; /* 0:short GI默认关闭 */ + config.group_rekey = WIFI_GROUP_REKEY; /* 86400:组播秘钥更新时间设置为1天 */ + config.protocol_mode = WIFI_PROTOCOL_MODE; /* 4:协议类型设置为802.11b + 802.11g + 802.11n + 802.11ax */ + config.hidden_ssid_flag = WIFI_HIDDEN_SSID_FLAG; /* 1:不隐藏SSID */ + if (wifi_set_softap_config_advance(&config) != 0) { + return -1; + } + /* 启动SoftAp接口 */ + if (wifi_softap_enable(&hapd_conf) != 0) { + return -1; + } + /* 配置DHCP服务器 */ + netif_p = netif_find(ifname); + if (netif_p == TD_NULL) { + (void)wifi_softap_disable(); + return -1; + } + if (netifapi_netif_set_addr(netif_p, &st_ipaddr, &st_netmask, &st_gw) != 0) { + (void)wifi_softap_disable(); + return -1; + } + if (netifapi_dhcps_start(netif_p, NULL, 0) != 0) { + (void)wifi_softap_disable(); + return -1; + } + printf("SoftAp start success.\r\n"); + return 0; +} + +static void radar_printf_res(radar_result_t *res) +{ + printf("[RADAR_SAMPLE] lb:%u, hb:%u, hm:%u\r\n", res->lower_boundary, res->upper_boundary, res->is_human_presence); + radar_ctrl_led(res); +} + +typedef struct { + uint8_t times; // 发射次数, 0-无限次 + uint8_t loop; // 单次雷达工作, TRx的波形数量 + uint8_t ant; // Rx天线数量 + uint8_t wave; // 波形选择, 0-320M/40M CTA, 1-160M/20M CW + uint8_t dbg_type; // 维测方式. 0-不外发维测数据, 1-外发脉压后的数据, 2-外发相干累加后的数据 + uint16_t period; // 雷达工作间隔 +} radar_driver_para_t; + +static void radar_set_driver_para_weakref(radar_driver_para_t *para) __attribute__ ((weakref("radar_set_driver_para"))); + +static void radar_init_para(void) +{ + radar_driver_para_t para; + para.ant = 0; + para.dbg_type = RADAR_DEFAULT_DBG_TYPE; + para.loop = RADAR_DEFAULT_LOOP; + para.period = RADAR_DEFAULT_PERIOD; + para.times = 1; // 1-使用软件控雷达, 0-使用硬件控雷达 + para.wave = RADAR_DEFAULT_WAVE; + radar_set_driver_para_weakref(¶); +} + +static void radar_demo_init(const char *arg) +{ + UNUSED(arg); + printf("[RADAR_SAMPLE] radar_demo_init softap!\r\n"); + radar_led_init(); + radar_start_softap(); + radar_init_para(); + uapi_radar_register_result_cb(radar_printf_res); + // 启动雷达 + osal_msleep(WIFI_START_SOFTAP_DELAY); + uapi_radar_set_status(RADAR_STATUS_START); + + for (;;) { + uapi_radar_set_delay_time(8); // 设置退出延迟时间为8S,目前最小时间为8 + osal_msleep(RADAR_STATUS_QUERY_DELAY); + uint8_t sts; + uapi_radar_get_status(&sts); + uint16_t time; + uapi_radar_get_delay_time(&time); + uint16_t iso; + uapi_radar_get_isolation(&iso); + } +} + +static void radar_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)radar_demo_init, 0, "RadarTask", RADAR_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, RADAR_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the radar_entry. */ +app_run(radar_entry); diff --git a/src/vendor/test/radar_led/radar_sta_sample/radar_sta_sample.c b/src/vendor/test/radar_led/radar_sta_sample/radar_sta_sample.c new file mode 100644 index 0000000000000000000000000000000000000000..25f603bd7fd31304933c6a5087226a3283138129 --- /dev/null +++ b/src/vendor/test/radar_led/radar_sta_sample/radar_sta_sample.c @@ -0,0 +1,200 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2024-2024. All rights reserved. \n + * + * Description: Radar samples function \n + * Author: @CompanyNameTag \n + */ + +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "td_base.h" +#include "td_type.h" +#include "stdlib.h" +#include "uart.h" +#include "soc_osal.h" +#include "radar_service.h" +#include "gpio.h" +#include "pinctrl.h" +#include "app_init.h" + +#define WIFI_IFNAME_MAX_SIZE 16 +#define WIFI_MAX_SSID_LEN 33 +#define WIFI_SCAN_AP_LIMIT 64 +#define WIFI_MAC_LEN 6 +#define WIFI_INIT_WAIT_TIME 5000 +#define WIFI_START_STA_DELAY 1000 + +#define RADAR_STATUS_CALI_ISO 4 +#define RADAR_STATUS_QUERY_DELAY 10000 + +#define RADAR_DEFAULT_LOOP 8 +#define RADAR_DEFAULT_PERIOD 5000 +#define RADAR_DEFAULT_DBG_TYPE 1 +#define RADAR_DEFAULT_WAVE 2 + +#define RADAR_API_NO_HUMAN 0 +#define RADAR_API_RANGE_CLOSE 50 +#define RADAR_API_RANGE_NEAR 100 +#define RADAR_API_RANGE_MEDIUM 200 +#define RADAR_API_RANGE_FAR 600 + +#define CONFIG_RED_LED_PIN 7 +#define CONFIG_GREEN_LED_PIN 11 +#define CONFIG_YELLOW_LED_PIN 10 + +#define RADAR_TASK_PRIO 24 +#define RADAR_TASK_STACK_SIZE 0x1000 + +// led档位控制参数 +typedef enum { + RADAR_INSIDE_1M, + RADAR_INSIDE_2M, + RADAR_INSIDE_6M, +} radar_led_gear_t; + +typedef struct { + uint8_t times; // 发射次数, 0-无限次 + uint8_t loop; // 单次雷达工作, TRx的波形数量 + uint8_t ant; // Rx天线数量 + uint8_t wave; // 波形选择, 0-320M/40M CTA, 1-160M/20M CW + uint8_t dbg_type; // 维测方式. 0-不外发维测数据, 1-外发脉压后的数据, 2-外发相干累加后的数据 + uint16_t period; // 雷达工作间隔 +} radar_driver_para_t; + +static void radar_set_driver_para_weakref(radar_driver_para_t *para) __attribute__ ((weakref("radar_set_driver_para"))); +static void gpio_set_value(pin_t pin) +{ + uapi_pin_set_mode(pin, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(pin, GPIO_DIRECTION_OUTPUT); +} + +static void radar_led_init(void) +{ + // 1. 初始化所有GPIO并设置GPIO的类型 + uapi_gpio_init(); + gpio_set_value(CONFIG_RED_LED_PIN); + gpio_set_value(CONFIG_GREEN_LED_PIN); + gpio_set_value(CONFIG_YELLOW_LED_PIN); +} + +static void radar_switch_green_on_off(bool onoff) +{ + if (onoff) { + uapi_gpio_set_val(CONFIG_GREEN_LED_PIN, GPIO_LEVEL_LOW); + } else { + uapi_gpio_set_val(CONFIG_GREEN_LED_PIN, GPIO_LEVEL_HIGH); + } +} + +static void radar_switch_yellow_on_off(bool onoff) +{ + if (onoff) { + uapi_gpio_set_val(CONFIG_YELLOW_LED_PIN, GPIO_LEVEL_LOW); + } else { + uapi_gpio_set_val(CONFIG_YELLOW_LED_PIN, GPIO_LEVEL_HIGH); + } +} + +static void radar_switch_red_on_off(bool onoff) +{ + if (onoff) { + uapi_gpio_set_val(CONFIG_RED_LED_PIN, GPIO_LEVEL_LOW); + } else { + uapi_gpio_set_val(CONFIG_RED_LED_PIN, GPIO_LEVEL_HIGH); + } +} + +static void radar_ctrl_led(radar_result_t *res) +{ + if (res->is_human_presence) { + radar_switch_green_on_off(true); + } else { + radar_switch_green_on_off(false); + } + if (res->lower_boundary == 0 && res->upper_boundary == RADAR_API_RANGE_NEAR) { + printf("R 1 meters\r\n"); + radar_switch_red_on_off(true); + radar_switch_yellow_on_off(true); + } else if ((res->lower_boundary == RADAR_API_RANGE_NEAR && res->upper_boundary == RADAR_API_RANGE_MEDIUM)) { + printf("R 2 meters\r\n"); + radar_switch_red_on_off(false); + radar_switch_yellow_on_off(true); + } else { + printf("R xxxx meters\r\n"); + radar_switch_red_on_off(false); + radar_switch_yellow_on_off(false); + } +} + +static errcode_t radar_start_sta(void) +{ + osal_msleep(WIFI_INIT_WAIT_TIME); + printf("STA try enable.\r\n"); + /* 创建STA接口 */ + if (wifi_sta_enable() != 0) { + printf("sta enbale fail !\r\n"); + return -1; + } + + /* 连接成功 */ + printf("STA connect success.\r\n"); + return 0; +} + +static void radar_printf_res(radar_result_t *res) +{ + printf("[RADAR_SAMPLE] lb:%u, hb:%u, hm:%u\r\n", res->lower_boundary, res->upper_boundary, res->is_human_presence); + + radar_ctrl_led(res); +} + +static void radar_init_para(void) +{ + radar_driver_para_t para; + para.ant = 0; + para.dbg_type = RADAR_DEFAULT_DBG_TYPE; + para.loop = RADAR_DEFAULT_LOOP; + para.period = RADAR_DEFAULT_PERIOD; + para.times = 1; // 1-使用软件控雷达, 0-使用硬件控雷达 + para.wave = RADAR_DEFAULT_WAVE; + radar_set_driver_para_weakref(¶); +} + +static void radar_demo_init(const char *arg) +{ + UNUSED(arg); + printf("[RADAR_SAMPLE] radar_demo_init sta!\r\n"); + radar_led_init(); + radar_start_sta(); + uapi_radar_register_result_cb(radar_printf_res); + radar_init_para(); + // 遍历1~13信道隔离度, 选取最佳隔离度进行雷达探测 + osal_msleep(WIFI_START_STA_DELAY); + uapi_radar_set_status(RADAR_STATUS_CALI_ISO); + for (;;) { + uapi_radar_set_delay_time(8); // 设置退出延迟时间为8S,目前最小时间为8 + osal_msleep(RADAR_STATUS_QUERY_DELAY); + uint8_t sts; + uapi_radar_get_status(&sts); + uint16_t time; + uapi_radar_get_delay_time(&time); + uint16_t iso; + uapi_radar_get_isolation(&iso); + } +} + +static void radar_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)radar_demo_init, 0, "RadarTask", RADAR_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, RADAR_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the pwm_entry. */ +app_run(radar_entry); \ No newline at end of file diff --git a/src/vendor/test/semaphore/CMakeLists.txt b/src/vendor/test/semaphore/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e7a595b9f8492f3ebf46ba025b7f68f5938dc302 --- /dev/null +++ b/src/vendor/test/semaphore/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/semaphore_example.c" PARENT_SCOPE) diff --git a/src/vendor/test/semaphore/README.md b/src/vendor/test/semaphore/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8b0fe58d7fc2179d23ce1904480e7e65e5cc5537 --- /dev/null +++ b/src/vendor/test/semaphore/README.md @@ -0,0 +1,115 @@ +## semaphore + +## 1.1 介绍 + +**功能介绍:** 本实验内容实现了两个任务之间同步获取信号量。 + +**软件概述:** 信号量(Semaphore)是一种实现任务间通信的机制,实现任务之间同步或临界资源的互斥访问。常用于协助一组相互竞争的任务来访问临界资源。在多任务系统中,各任务之间需要同步或互斥实现临界资源的保护,信号量功能可以为用户提供这方面的支持。通常一个信号量的计数值用于对应有效的资源数表示剩下的可被占用的互斥资源数。 + +**硬件概述:** 核心板。硬件搭建要求如图所示: + + image-20240401152853303 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V00 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + ![image-20240401171259237](../../../docs/pic/semaphore/image-20240401171259237.png) + +## 1.4 接口说明 + +### 1.4.1 osal_sem_init() + +| **定义:** | int osal_sem_init(osal_semaphore *sem, int val); | +| ------------ | ------------------------------------------------ | +| **功能:** | 创建信号量 | +| **参数:** | sem:信号量对象
val:可用信号量初始化数量 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\semaphore\osal_semaphore.h | + +### 1.4.2 osal_sem_binary_sem_init() + +| 定义: | int osal_sem_binary_sem_init(osal_semaphore *sem, int val); | +| ------------ | ----------------------------------------------------------- | +| **功能:** | 创建二进制信号量 | +| **参数:** | sem:信号量对象
val:可用信号量初始化数量,范围[0, 1] | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\semaphore\osal_semaphore.h | + +### 1.4.3 osal_sem_down_timeout() + +| **定义:** | int osal_sem_down_timeout(osal_semaphore *sem, unsigned int timeout); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 阻塞获取指定信号量,单位:ms | +| **参数:** | sem:信号量对象
timeout:超时时间 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\semaphore\osal_semaphore.h | + +### 1.4.4 osal_sem_up() + +| **定义:** | void osal_sem_up(osal_semaphore *sem); | +| ------------ | ---------------------------------------------- | +| **功能:** | 释放指定信号量 | +| **参数:** | sem:信号量对象 | +| **返回值:** | OSAL_SUCCESS:成功 Other:OSAL_FAILURE | +| **依赖:** | kernel\osal\include\semaphore\osal_semaphore.h | + +## 1.5 具体流程 + + 步骤一:创建信号量osal_sem_init或者osal_sem_binary_sem_init. + + 步骤二:申请信号量osal_sem_down_timeout。 + + 信号量有3种申请模式: + +​ 无阻塞模式:任务需要申请信号量,若当前信号量的任务数没有到信号量设定的上限,则申请成功。否则,立即返回申请失败。超时时间设置为0。 + +​ 永久阻塞模式:任务需要申请信号量,若当前信号量的任务数没有到信号量设定的上限,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,直到有其他任务释放该信号 量,阻塞任务才会重新得以执行。超时时间设置为HI_SYS_WAIT_FOREVER。 + +​ 定时阻塞模式:任务需要申请信号量,若当前信号量的任务数没有到信号量设定的上限,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级.高者继续执行。任务进入阻塞态后,指定时间超时前有其他任务 释放该信号量,或者用户指定时间超时后,阻塞任务才会重新得以执行。超时时间设置为合理值。 + + 步骤三:释放信号量osal_sem_up。如果有任务阻塞于指定信号量,则唤醒该信号量阻塞队列上的第一个任务。 该任务进入就绪态,并进行调度。 如果没有任务阻塞于指定信号量,释放信号量成功。 + + 步骤四:删除信号量osal_sem_destroy。 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”semaphore“。 + + ![image-20240401152929178](../../../docs/pic/common/image-20240401152929178.png) + +- 步骤二:将open_cfbb\vendor\hispark\semaphore文件里面内容拷贝到**步骤一创建的Sample文件夹中”semaphore“**。 + +![image-20240401162502575](../../../docs/pic/semaphore/image-20240401162502575.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support SEMAPHORE Sample”,点击Save,关闭弹窗。 + + image-20240401153033024image-20240401153046561image-20240401162820928 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240401153005118](../../../docs/pic/common/image-20240401153005118.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240401153012691](../../../docs/pic/common/image-20240401153012691.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240401153019843](../../../docs/pic/common/image-20240401153019843.png) + +- 步骤七:软件烧录成功后,按一下开发板的RESET按键复位开发板,烧录完成后,串口打印信息如下。 + + ![image-20240401171259237](../../../docs/pic/semaphore/image-20240401171259237.png) \ No newline at end of file diff --git a/src/vendor/test/semaphore/semaphore_example.c b/src/vendor/test/semaphore/semaphore_example.c new file mode 100644 index 0000000000000000000000000000000000000000..89f2543554ad018f5655c52e847474a20434a070 --- /dev/null +++ b/src/vendor/test/semaphore/semaphore_example.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "common.h" +#include "osal_wait.h" +#include "soc_errno.h" +#include "soc_osal.h" +#include "app_init.h" + +#define TASK_PRO_TASK1 21 +#define TASK_PRO_TASK2 20 +#define SEM_TASK_STACK_SIZE 0x1000 +#define SEM_TASK_PRIO 24 +#define TASK_STACK_SIZE 0x1000 + +static osal_semaphore g_sem_id; + +void example_sem_task1(void) +{ + uint32_t ret; + printf("example_sem_task1 try get sem g_usSemID ,timeout 100 ms.\n"); + /*定时阻塞模式申请信号量,定时时间为100ms*/ + ret = osal_sem_down_timeout(&g_sem_id, 100); + /*申请到信号量*/ + if (OSAL_SUCCESS == ret) { + osal_sem_up(&g_sem_id); + } else { + /*定时时间到,未申请到信号量*/ + printf("example_sem_task1 timeout and try get sem g_usSemID wait forever.\n"); + /*永久阻塞模式申请信号量*/ + ret = osal_sem_down_timeout(&g_sem_id, OSAL_WAIT_FOREVER); + printf("example_sem_task1 wait_forever and get sem g_usSemID .\n"); + if (OSAL_SUCCESS == ret) { + osal_sem_up(&g_sem_id); + } + } +} +void example_sem_task2(void) +{ + uint32_t ret; + printf("example_sem_task2 try get sem g_usSemID wait forever.\n"); + /*永久阻塞模式申请信号量*/ + ret = osal_sem_down_timeout(&g_sem_id, OSAL_WAIT_FOREVER); + if (OSAL_SUCCESS == ret) { + printf("example_sem_task2 get sem g_usSemID and then delay 200ms .\n"); + } + /*任务休眠200ms*/ + osal_mdelay(200); + printf("example_sem_task2 post sem g_usSemID .\n"); + /*释放信号量*/ + osal_sem_up(&g_sem_id); +} + +static void example_task_sem(void) +{ + uint32_t ret; + osal_task *taskid1, *taskid2; + /*创建信号量*/ + osal_sem_init(&g_sem_id, 0); + /*锁任务调度*/ + osal_kthread_lock(); + // 创建任务1 + taskid1 = osal_kthread_create((osal_kthread_handler)example_sem_task1, NULL, "example_task1", TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid1, TASK_PRO_TASK1); + if (ret != OSAL_SUCCESS) { + printf("create task1 failed .\n"); + } + // 创建任务2 + taskid2 = osal_kthread_create((osal_kthread_handler)example_sem_task2, NULL, "example_task2", TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid2, TASK_PRO_TASK2); + if (ret != OSAL_SUCCESS) { + printf("create task2 failed .\n"); + } + osal_kthread_unlock(); + osal_sem_up(&g_sem_id); + /*任务休眠400ms*/ + osal_mdelay(400); + /*删除信号量*/ + osal_sem_destroy(&g_sem_id); + /*删除任务*/ + osal_kthread_destroy(taskid1, 0); + osal_kthread_destroy(taskid2, 0); +} + +static void example_task_entry_sem(void) +{ + uint32_t ret; + osal_task *taskid; + // 创建任务调度 + osal_kthread_lock(); + // 创建任务1 + taskid = osal_kthread_create((osal_kthread_handler)example_task_sem, NULL, "example_task_sem", SEM_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid, SEM_TASK_PRIO); + if (ret != OSAL_SUCCESS) { + printf("create task1 failed .\n"); + } + osal_kthread_unlock(); +} + +/* Run the muxTask_entry. */ +app_run(example_task_entry_sem); diff --git a/src/vendor/test/servo/CMakeLists.txt b/src/vendor/test/servo/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7ae7ddf2ce3c85449f6bce746774dd706f0fefa8 --- /dev/null +++ b/src/vendor/test/servo/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/sg92r_control.c" PARENT_SCOPE) diff --git a/src/vendor/test/servo/README.md b/src/vendor/test/servo/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a507ae5e8a372836b76193d13bd032d403e0d7a5 --- /dev/null +++ b/src/vendor/test/servo/README.md @@ -0,0 +1,100 @@ +# servo + +## 1.1 介绍 + +**功能介绍:** 通过GPIO2控制舵机转动90°、45°、0°、-45°、-90°。。 + +**软件概述:** GPIO引脚输出高低电平状态。 + +**硬件概述:** 核心板、交通灯板、SG92R舵机。SG92R频率为50HZ,核心板最小频率不支持50HZ,只能采用GPIO模拟的方式实现舵机转动,SG92R舵机转动要求如下图。硬件搭建要求如图所示: + + 参考[核心板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf) + + image-20240418100509871 image-20240418101831113 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 舵机转动90°、45°、0°、-45°、-90°。 + + image-20240418101831113 + +## 1.4 接口介绍 + +### 1.4.1 uapi_gpio_set_dir() + +| **定义:** | errcode_t uapi_gpio_set_dir(pin_t pin, gpio_direction_t dir); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置GPIO的输入输出方向函数 | +| **参数:** | pin: io引脚
dir:输入输出方向 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +### 1.4.2 uapi_gpio_set_val() + +| 定义: | errcode_t uapi_gpio_set_val(pin_t pin, gpio_level_t level); | +| ------------ | ----------------------------------------------------------- | +| **功能:** | 设置GPIO的输出状态 | +| **参数:** | pin:io引脚
level:设置输出为高或低 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +### 1.4.3 uapi_gpio_toggle() + +| **定义:** | errcode_t uapi_gpio_toggle(pin_t pin); | +| ------------ | -------------------------------------- | +| **功能:** | 翻转输出GPIO电平状态. | +| **参数:** | pin:io引脚 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +## 1.5 具体实现 + + 步骤一:设置GPIO为输出模式。 + + 步骤二:设置GPIO输出为高或低。 + + 步骤三:通过输出GPIO高低电平状态并模拟对应PWM波形。 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”servo“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\servo文件里面内容拷贝到**步骤一创建的Sample文件夹中”servo“**。 + + ![image-20240418103106401](../../../docs/pic/servo/image-20240418103106401.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support LED Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240418103238518 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 +- + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七“软件烧录成功后,按一下开发板的RESET按键复位开发板,可以发现舵机转动90°、45°、0°、-45°、-90°。 +- + image-20240418101831113 \ No newline at end of file diff --git a/src/vendor/test/servo/sg92r_control.c b/src/vendor/test/servo/sg92r_control.c new file mode 100644 index 0000000000000000000000000000000000000000..13d363550f6399c3b1f36abf8894958e209d6145 --- /dev/null +++ b/src/vendor/test/servo/sg92r_control.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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. + */ + +/* 由于舵机的频率为50HZ,PWM不支持这么小的频率,所以采用GPIO模拟PWM波形 */ + +#include "pinctrl.h" +#include "common_def.h" +#include "soc_osal.h" +#include "gpio.h" +#include "hal_gpio.h" +#include "systick.h" +#include "test_suite_log.h" +#include "watchdog.h" +#include "app_init.h" + +#define COUNT 10 // 通过计算舵机转到对应角度需要发送10个左右的波形 +#define SG92R_TASK_STACK_SIZE 0x1000 +#define SG92R_TASK_PRIO 17 +#define BSP_SG92R 2 +#define FREQ_TIME 20000 + +void SetAngle(unsigned int duty) +{ + unsigned int time = FREQ_TIME; + + uapi_gpio_set_val(BSP_SG92R, GPIO_LEVEL_HIGH); + uapi_systick_delay_us(duty); + uapi_gpio_set_val(BSP_SG92R, GPIO_LEVEL_LOW); + uapi_systick_delay_us(time - duty); +} + +/* The steering gear is centered + * 1、依据角度与脉冲的关系,设置高电平时间为1500微秒 + * 2、不断地发送信号,控制舵机居中 + */ +void RegressMiddle(void) +{ + unsigned int angle = 1500; + for (int i = 0; i < COUNT; i++) { + SetAngle(angle); + } +} + +/* Turn 90 degrees to the right of the steering gear + * 1、依据角度与脉冲的关系,设置高电平时间为500微秒 + * 2、不断地发送信号,控制舵机向右旋转90度 + */ +/* Steering gear turn right */ +void EngineTurnRight(void) +{ + unsigned int angle = 500; + for (int i = 0; i < COUNT; i++) { + SetAngle(angle); + } +} + +/* Turn 90 degrees to the left of the steering gear + * 1、依据角度与脉冲的关系,设置高电平时间为2500微秒 + * 2、不断地发送信号,控制舵机向左旋转90度 + */ +/* Steering gear turn left */ +void EngineTurnLeft(void) +{ + unsigned int angle = 2500; + for (int i = 0; i < COUNT; i++) { + SetAngle(angle); + } +} + +void S92RInit(void) +{ + uapi_pin_set_mode(BSP_SG92R, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(BSP_SG92R, GPIO_DIRECTION_OUTPUT); + uapi_gpio_set_val(BSP_SG92R, GPIO_LEVEL_LOW); +} + +void Sg92RTask(void) +{ + unsigned int time = 200; + S92RInit(); + + while (1) { + uapi_watchdog_kick(); + /* 舵机归中 Steering gear centering */ + RegressMiddle(); + uapi_systick_delay_ms(time); + + /* + * 舵机左转90度 + * Steering gear turns 90 degrees to the left + */ + EngineTurnLeft(); + uapi_systick_delay_ms(time); + + /* 舵机归中 Steering gear centering */ + RegressMiddle(); + uapi_systick_delay_ms(time); + + /* + * 舵机右转90度 + * Steering gear turns right 90 degrees + */ + EngineTurnRight(); + uapi_systick_delay_ms(time); + + /* 舵机归中 Steering gear centering */ + RegressMiddle(); + uapi_systick_delay_ms(time); + } +} + +void SG92RSampleEntry(void) +{ + uint32_t ret; + osal_task *taskid; + // 创建任务调度 + osal_kthread_lock(); + // 创建任务1 + taskid = osal_kthread_create((osal_kthread_handler)Sg92RTask, NULL, "Sg92RTask", SG92R_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid, SG92R_TASK_PRIO); + if (ret != OSAL_SUCCESS) { + printf("create task1 failed .\n"); + } + osal_kthread_unlock(); +} +app_run(SG92RSampleEntry); \ No newline at end of file diff --git a/src/vendor/test/sle_throughput/CMakeLists.txt b/src/vendor/test/sle_throughput/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5c83d02c8f67e802d955e36ccd281be8321843be --- /dev/null +++ b/src/vendor/test/sle_throughput/CMakeLists.txt @@ -0,0 +1,9 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +if(DEFINED CONFIG_SAMPLE_SUPPORT_SLE_SERVER_SPEED) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/sle_server_speed/src/sle_server_adv.c" "${CMAKE_CURRENT_SOURCE_DIR}/sle_server_speed/src/sle_uuid_server.c" "${CMAKE_CURRENT_SOURCE_DIR}/sle_server_speed/inc" PARENT_SCOPE) +elseif(DEFINED CONFIG_SAMPLE_SUPPORT_SLE_CLIENT_SPEED) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/sle_client_speed/src/sle_uuid_client.c" "${CMAKE_CURRENT_SOURCE_DIR}/sle_client_speed/inc" PARENT_SCOPE) +endif() \ No newline at end of file diff --git a/src/vendor/test/sle_throughput/Kconfig b/src/vendor/test/sle_throughput/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..d0fb87fbe78a5cfee89e88af909fccb74ce58950 --- /dev/null +++ b/src/vendor/test/sle_throughput/Kconfig @@ -0,0 +1,19 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +config SAMPLE_SUPPORT_SLE_SERVER_SPEED + bool + prompt "Support SLE_SERVER_SPEED Sample." + default n + depends on SAMPLE_SUPPORT_SLE_THROUGHPUT + help + This option means support SLE_SERVER_SPEED Sample. + +config SAMPLE_SUPPORT_SLE_CLIENT_SPEED + bool + prompt "Support SLE_CLIENT_SPEED Sample." + default n + depends on SAMPLE_SUPPORT_SLE_THROUGHPUT + help + This option means support SLE_CLIENT_SPEED Sample. \ No newline at end of file diff --git a/src/vendor/test/sle_throughput/README.md b/src/vendor/test/sle_throughput/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f6e39426365fa70c406ce3aa69bfc63d5df2e034 --- /dev/null +++ b/src/vendor/test/sle_throughput/README.md @@ -0,0 +1,39 @@ +# 1. 使用介绍 + +* 步骤一:在open_cfbb\src\application\samples文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”sle_distribute_network“。 + + ![image-20240402193714218](../../../docs/pic/wifidemo/image-20240402193714218.png) + +* 步骤二:将open_cfbb\vendor\hihope\sle_distribute_network文件里面内容拷贝到**步骤一创建的Sample文件夹中”sle_distribute_network“**下。 + + ![image-20240430101008080](../../../docs/pic/sle_throughput/image-20240430101008080.png) + +* 步骤三:将open_cfbb\src\application\samples\CMakeLists.txt新增如下内容。 + + ![image-20240430101031355](../../../docs/pic/sle_throughput/image-20240430101031355.png) + +* 步骤四:将open_cfbb\src\application\samples\Kconfig新增如下内容。 + + ![image-20240430101058968](../../../docs/pic/sle_throughput/image-20240430101058968.png) + +* 步骤五:点击如下图标,选择KConfig,具体选择路径“Application/Enable Sample ”,如果选择编译sle_server_speed,在弹出框中选择“support SLE_SERVER_SPEED Sample”,点击Save,关闭弹窗;如果选择编译sle_client_speed,在弹出框中选择“support SLE_CLIENT_SPEED Sample”,点击Save,,关闭弹窗。(需要准备两块开发板,选择不同的编译选项,烧录不同的镜像) + + ![image-20240430101120243](../../../docs/pic/sle_throughput/image-20240430101120243.png) + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +* 步骤七:先复位client端,在复位server端(注意这里板子需要离的较近)。 + + image-20240430101525430 + +![image-20240430101512067](../../../docs/pic/sle_throughput/image-20240430101512067.png) diff --git a/src/vendor/test/sle_throughput/sle_client_speed/CMakeLists.txt b/src/vendor/test/sle_throughput/sle_client_speed/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..49e21fecc7e678921d33e6bf572bac700d86714a --- /dev/null +++ b/src/vendor/test/sle_throughput/sle_client_speed/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(src) + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/src/vendor/test/sle_throughput/sle_client_speed/inc/sle_uuid_client.h b/src/vendor/test/sle_throughput/sle_client_speed/inc/sle_uuid_client.h new file mode 100644 index 0000000000000000000000000000000000000000..635408b73821744f27abbeb17c0f0a666906791a --- /dev/null +++ b/src/vendor/test/sle_throughput/sle_client_speed/inc/sle_uuid_client.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) @CompanyNameMagicTag 2022. All rights reserved. + * + * Description: SLE private service register sample of client. + */ + +/** + * @defgroup SLE UUID CLIENT API + * @ingroup + * @{ + */ + +#ifndef SLE_CLIENT_ADV_H +#define SLE_CLIENT_ADV_H + +/** + * @if Eng + * @brief sle uuid client init. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle uuid客户端初始化。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +void sle_client_init(ssapc_notification_callback notification_cb, ssapc_indication_callback indication_cb); + +/** + * @if Eng + * @brief sle start scan. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle启动扫描。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +void sle_start_scan(void); + +#endif \ No newline at end of file diff --git a/src/vendor/test/sle_throughput/sle_client_speed/src/CMakeLists.txt b/src/vendor/test/sle_throughput/sle_client_speed/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..fe6546943e623f44d204e8f2d55c06ab724f9fe9 --- /dev/null +++ b/src/vendor/test/sle_throughput/sle_client_speed/src/CMakeLists.txt @@ -0,0 +1,7 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" + "${CMAKE_CURRENT_SOURCE_DIR}/sle_uuid_client.c" + PARENT_SCOPE) diff --git a/src/vendor/test/sle_throughput/sle_client_speed/src/sle_uuid_client.c b/src/vendor/test/sle_throughput/sle_client_speed/src/sle_uuid_client.c new file mode 100644 index 0000000000000000000000000000000000000000..3924f0fbb9e08ec557b213b406c4b4d1534a7179 --- /dev/null +++ b/src/vendor/test/sle_throughput/sle_client_speed/src/sle_uuid_client.c @@ -0,0 +1,345 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2022. All rights reserved. + * + * Description: SLE private service register sample of client. + */ +#include "securec.h" +#include "test_suite_uart.h" +#include "sle_device_discovery.h" +#include "sle_connection_manager.h" +#include "soc_osal.h" +#include "sle_ssap_client.h" +#include "../inc/sle_uuid_client.h" +#include "app_init.h" +#include "systick.h" +#include "tcxo.h" +#include "los_memory.h" + +#undef THIS_FILE_ID +#define THIS_FILE_ID BTH_GLE_SAMPLE_UUID_CLIENT + +#define SLE_MTU_SIZE_DEFAULT 250 +#define SLE_SEEK_INTERVAL_DEFAULT 100 +#define SLE_SEEK_WINDOW_DEFAULT 100 +#define UUID_16BIT_LEN 2 +#define UUID_128BIT_LEN 16 + +int g_rx_buffer_size = 0; +char* g_rev_start_ret = NULL; +char* g_rev_stop_ret = NULL; +uint64_t g_start_time = 0; +uint64_t g_stop_time = 0; + +sle_announce_seek_callbacks_t g_seek_cbk = {0}; +sle_connection_callbacks_t g_connect_cbk = {0}; +ssapc_callbacks_t g_ssapc_cbk = {0}; +sle_addr_t g_remote_addr = {0}; +uint16_t g_conn_id = 0; +ssapc_find_service_result_t g_find_service_result = {0}; + +void sle_sample_sle_enable_cbk(errcode_t status) +{ + if (status == 0) { + sle_start_scan(); + } +} + +void sle_sample_seek_enable_cbk(errcode_t status) +{ + if (status == 0) { + return; + } +} + +void sle_sample_seek_disable_cbk(errcode_t status) +{ + if (status == 0) { + sle_connect_remote_device(&g_remote_addr); + } +} + +void sle_sample_seek_result_info_cbk(sle_seek_result_info_t *seek_result_data) +{ + if (seek_result_data != NULL) { + (void)memcpy_s(&g_remote_addr, sizeof(sle_addr_t), &seek_result_data->addr, sizeof(sle_addr_t)); + sle_stop_seek(); + } +} +int i = 0; +uint64_t count_before_get_us; +uint64_t count_after_get_us; +static char templine[32] = {0}; +static void sle_uart_notification_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data, + errcode_t status) +{ + unused(client_id); + unused(conn_id); + unused(status); + i++; + if (i == 1) { + count_before_get_us = uapi_tcxo_get_us(); + } else if (i == 1000) { + count_after_get_us = uapi_tcxo_get_us(); + printf("count_after_get_us = %llu, count_before_get_us = %llu\r\n", count_after_get_us, count_before_get_us); + printf("count_us = %llu, data[0] = %0X, data[1] = %0x\r\n", count_after_get_us - count_before_get_us, data->data[0], data->data[1]); + float time = (float)(count_after_get_us - count_before_get_us) / 1000000.000; + sprintf(templine, ": %f", time); + printf("speed = %s s\r\n", templine); + float speed = 235 * 1000 * 8 / time; + sprintf(templine, ": %f", speed); + printf("speed = %s bps\r\n", templine); + LOS_MEM_POOL_STATUS status; + LOS_MemInfoGet(m_aucSysMem0, &status); + printf("[SYS INFO] mem: used:%u, free:%u\r\n", status.uwTotalUsedSize, status.uwTotalFreeSize); + i = 0; + } + +} + +static void sle_uart_indication_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data, + errcode_t status) +{ + unused(client_id); + unused(conn_id); + unused(status); + osal_printk("\n sle_uart_indication_cb sle uart recived data : %s\r\n", data->data); +} + +void sle_sample_seek_cbk_register(void) +{ + g_seek_cbk.sle_enable_cb = sle_sample_sle_enable_cbk; + g_seek_cbk.seek_enable_cb = sle_sample_seek_enable_cbk; + g_seek_cbk.seek_disable_cb = sle_sample_seek_disable_cbk; + g_seek_cbk.seek_result_cb = sle_sample_seek_result_info_cbk; +} + +void sle_sample_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr, + sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) +{ + test_suite_uart_sendf("[ssap client] conn state changed conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0], + addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + test_suite_uart_sendf("[ssap client] conn state changed disc_reason:0x%x\n", disc_reason); + if (conn_state == SLE_ACB_STATE_CONNECTED) { + if (pair_state == SLE_PAIR_NONE) { + sle_pair_remote_device(&g_remote_addr); + } + g_conn_id = conn_id; + } +} + +void sle_sample_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + test_suite_uart_sendf("[ssap client] pair complete conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0], + addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + if (status == 0) { + ssap_exchange_info_t info = {0}; + info.mtu_size = SLE_MTU_SIZE_DEFAULT; + info.version = 1; + ssapc_exchange_info_req(1, g_conn_id, &info); + } + // sle_connection_param_update_t parame = {0}; + // parame.conn_id = conn_id; + // parame.interval_min = 0xA; + // parame.interval_max = 0xA; //18.75ms + // parame.max_latency = 0; + // parame.supervision_timeout = 0x1f3; + // sle_update_connect_param(¶me); +} + +void sle_sample_update_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_evt_t *param) +{ + test_suite_uart_sendf("[ssap client] updat state changed conn_id:%d, interval = %02x\n", conn_id, param->interval); + if (status == 0) { + } +} + +void sle_sample_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param) +{ + test_suite_uart_sendf("[ssap client] updat req state changed conn_id:%d, interval_min = %02x, interval_max = %02x\n", conn_id, param->interval_min, param->interval_max); + if (status == 0) { + } +} + +void sle_sample_connect_cbk_register(void) +{ + g_connect_cbk.connect_state_changed_cb = sle_sample_connect_state_changed_cbk; + g_connect_cbk.pair_complete_cb = sle_sample_pair_complete_cbk; + g_connect_cbk.connect_param_update_req_cb = sle_sample_update_req_cbk; + g_connect_cbk.connect_param_update_cb = sle_sample_update_cbk; +} + +void sle_sample_exchange_info_cbk(uint8_t client_id, uint16_t conn_id, ssap_exchange_info_t *param, + errcode_t status) +{ + test_suite_uart_sendf("[ssap client] pair complete client id:%d status:%d\n", client_id, status); + test_suite_uart_sendf("[ssap client] exchange mtu, mtu size: %d, version: %d.\n", + param->mtu_size, param->version); + + ssapc_find_structure_param_t find_param = {0}; + find_param.type = SSAP_FIND_TYPE_PRIMARY_SERVICE; + find_param.start_hdl = 1; + find_param.end_hdl = 0xFFFF; + ssapc_find_structure(0, conn_id, &find_param); +} + +void sle_sample_find_structure_cbk(uint8_t client_id, uint16_t conn_id, ssapc_find_service_result_t *service, + errcode_t status) +{ + test_suite_uart_sendf("[ssap client] find structure cbk client: %d conn_id:%d status: %d \n", + client_id, conn_id, status); + test_suite_uart_sendf("[ssap client] find structure start_hdl:[0x%02x], end_hdl:[0x%02x], uuid len:%d\r\n", + service->start_hdl, service->end_hdl, service->uuid.len); + if (service->uuid.len == UUID_16BIT_LEN) { + test_suite_uart_sendf("[ssap client] structure uuid:[0x%02x][0x%02x]\r\n", + service->uuid.uuid[14], service->uuid.uuid[15]); /* 14 15: uuid index */ + } else { + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + test_suite_uart_sendf("[ssap client] structure uuid[%d]:[0x%02x]\r\n", idx, service->uuid.uuid[idx]); + } + } + g_find_service_result.start_hdl = service->start_hdl; + g_find_service_result.end_hdl = service->end_hdl; + memcpy_s(&g_find_service_result.uuid, sizeof(sle_uuid_t), &service->uuid, sizeof(sle_uuid_t)); +} + +void sle_sample_find_structure_cmp_cbk(uint8_t client_id, uint16_t conn_id, + ssapc_find_structure_result_t *structure_result, errcode_t status) +{ + test_suite_uart_sendf("[ssap client] find structure cmp cbk client id:%d status:%d type:%d uuid len:%d \r\n", + client_id, status, structure_result->type, structure_result->uuid.len); + if (structure_result->uuid.len == UUID_16BIT_LEN) { + test_suite_uart_sendf("[ssap client] find structure cmp cbk structure uuid:[0x%02x][0x%02x]\r\n", + structure_result->uuid.uuid[14], structure_result->uuid.uuid[15]); /* 14 15: uuid index */ + } else { + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + test_suite_uart_sendf("[ssap client] find structure cmp cbk structure uuid[%d]:[0x%02x]\r\n", idx, + structure_result->uuid.uuid[idx]); + } + } + uint8_t data[] = {0x11, 0x22, 0x33, 0x44}; + uint8_t len = sizeof(data); + ssapc_write_param_t param = {0}; + param.handle = g_find_service_result.start_hdl; + param.type = SSAP_PROPERTY_TYPE_VALUE; + param.data_len = len; + param.data = data; + ssapc_write_req(0, conn_id, ¶m); +} + +void sle_sample_find_property_cbk(uint8_t client_id, uint16_t conn_id, + ssapc_find_property_result_t *property, errcode_t status) +{ + test_suite_uart_sendf("[ssap client] find property cbk, client id: %d, conn id: %d, operate ind: %d, " + "descriptors count: %d status:%d.\n", client_id, conn_id, property->operate_indication, + property->descriptors_count, status); + for (uint16_t idx = 0; idx < property->descriptors_count; idx++) { + test_suite_uart_sendf("[ssap client] find property cbk, descriptors type [%d]: 0x%02x.\n", + idx, property->descriptors_type[idx]); + } + if (property->uuid.len == UUID_16BIT_LEN) { + test_suite_uart_sendf("[ssap client] find property cbk, uuid: %02x %02x.\n", + property->uuid.uuid[14], property->uuid.uuid[15]); /* 14 15: uuid index */ + } else if (property->uuid.len == UUID_128BIT_LEN) { + for (uint16_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + test_suite_uart_sendf("[ssap client] find property cbk, uuid [%d]: %02x.\n", + idx, property->uuid.uuid[idx]); + } + } +} + +void sle_sample_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_write_result_t *write_result, + errcode_t status) +{ + test_suite_uart_sendf("[ssap client] write cfm cbk, client id: %d status:%d.\n", client_id, status); + ssapc_read_req(0, conn_id, write_result->handle, write_result->type); +} + +void sle_sample_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *read_data, + errcode_t status) +{ + test_suite_uart_sendf("[ssap client] read cfm cbk client id: %d conn id: %d status: %d\n", + client_id, conn_id, status); + test_suite_uart_sendf("[ssap client] read cfm cbk handle: %d, type: %d , len: %d\n", + read_data->handle, read_data->type, read_data->data_len); + for (uint16_t idx = 0; idx < read_data->data_len; idx++) { + test_suite_uart_sendf("[ssap client] read cfm cbk[%d] 0x%02x\r\n", idx, read_data->data[idx]); + } +} + +void sle_sample_ssapc_cbk_register(ssapc_notification_callback notification_cb, ssapc_notification_callback indication_cb) +{ + g_ssapc_cbk.exchange_info_cb = sle_sample_exchange_info_cbk; + g_ssapc_cbk.find_structure_cb = sle_sample_find_structure_cbk; + g_ssapc_cbk.find_structure_cmp_cb = sle_sample_find_structure_cmp_cbk; + g_ssapc_cbk.ssapc_find_property_cbk = sle_sample_find_property_cbk; + g_ssapc_cbk.write_cfm_cb = sle_sample_write_cfm_cbk; + g_ssapc_cbk.read_cfm_cb = sle_sample_read_cfm_cbk; + g_ssapc_cbk.notification_cb = notification_cb; + g_ssapc_cbk.indication_cb = indication_cb; +} + +void sle_connect(void) +{ + sle_default_connect_param_t param = {0}; + param.enable_filter_policy = 0; + param.gt_negotiate = 0; + param.initiate_phys = 1; + param.max_interval = 0xa; + param.min_interval = 0xa; + param.scan_interval = 400; + param.scan_window = 20; + param.timeout = 0x1fc; + sle_default_connection_param_set(¶m); +} + +void sle_client_init(ssapc_notification_callback notification_cb, ssapc_indication_callback indication_cb) +{ + uint8_t local_addr[SLE_ADDR_LEN] = { 0x13, 0x67,0x5c, 0x07, 0x00, 0x51 };//0x04-->0x07 + sle_addr_t local_address; + local_address.type = 0; + (void)memcpy_s(local_address.addr, SLE_ADDR_LEN, local_addr, SLE_ADDR_LEN); + sle_sample_seek_cbk_register(); + sle_connect(); + sle_sample_connect_cbk_register(); + sle_sample_ssapc_cbk_register(notification_cb, indication_cb); + sle_announce_seek_register_callbacks(&g_seek_cbk); + sle_connection_register_callbacks(&g_connect_cbk); + ssapc_register_callbacks(&g_ssapc_cbk); + enable_sle(); + sle_set_local_addr(&local_address); +} + +void sle_start_scan() +{ + sle_seek_param_t param = {0}; + param.own_addr_type = 0; + param.filter_duplicates = 0; + param.seek_filter_policy = 0; + param.seek_phys = 1; + param.seek_type[0] = 0; + param.seek_interval[0] = SLE_SEEK_INTERVAL_DEFAULT; + param.seek_window[0] = SLE_SEEK_WINDOW_DEFAULT; + sle_set_seek_param(¶m); + sle_start_seek(); +} + +int sle_speed_init(void) +{ + sle_client_init(sle_uart_notification_cb, sle_uart_indication_cb); + return 0; +} + +static void sle_speed_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)sle_speed_init, 0, "RadarTask", 0x2000); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, 24); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +// /* Run the blinky_entry. */ +app_run(sle_speed_entry); \ No newline at end of file diff --git a/src/vendor/test/sle_throughput/sle_server_speed/CMakeLists.txt b/src/vendor/test/sle_throughput/sle_server_speed/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..49e21fecc7e678921d33e6bf572bac700d86714a --- /dev/null +++ b/src/vendor/test/sle_throughput/sle_server_speed/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(src) + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/src/vendor/test/sle_throughput/sle_server_speed/inc/sle_server_adv.h b/src/vendor/test/sle_throughput/sle_server_speed/inc/sle_server_adv.h new file mode 100644 index 0000000000000000000000000000000000000000..f2f38a67a91b44a84bb1c89f8c18bbddfd0ac387 --- /dev/null +++ b/src/vendor/test/sle_throughput/sle_server_speed/inc/sle_server_adv.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. + * + * Description: SLE ADV Config. + */ + +/** + * @defgroup bluetooth_sle_adv API + * @ingroup + * @{ + */ + +#ifndef SLE_SERVER_ADV_H +#define SLE_SERVER_ADV_H + +/** + * @if Eng + * @brief Definitaion of BLE ADV 通用广播结构. + * @else + * @brief SLE 广播普通数据结构。 + * @endif + */ +struct sle_adv_common_value { + uint8_t length; + uint8_t type; + uint8_t value; +}; + +/** + * @if Eng + * @brief Definitaion of BLE ADV Channel mapping. + * @else + * @brief SLE 广播信道映射。 + * @endif + */ +typedef enum { + SLE_ADV_CHANNEL_MAP_77 = 0x01, + SLE_ADV_CHANNEL_MAP_78 = 0x02, + SLE_ADV_CHANNEL_MAP_79 = 0x04, + SLE_ADV_CHANNEL_MAP_DEFAULT = 0x07 +} sle_adv_channel_map; + +/** + * @if Eng + * @brief Definitaion of SLE ADV Data Type. + * @else + * @brief SLE 广播数据类型 + * @endif + */ +typedef enum { + SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL = 0x01, /*!< 发现等级 */ + SLE_ADV_DATA_TYPE_ACCESS_MODE = 0x02, /*!< 接入层能力 */ + SLE_ADV_DATA_TYPE_SERVICE_DATA_16BIT_UUID = 0x03, /*!< 标准服务数据信息 */ + SLE_ADV_DATA_TYPE_SERVICE_DATA_128BIT_UUID = 0x04, /*!< 自定义服务数据信息 */ + SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x05, /*!< 完整标准服务标识列表 */ + SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x06, /*!< 完整自定义服务标识列表 */ + SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x07, /*!< 部分标准服务标识列表 */ + SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x08, /*!< 部分自定义服务标识列表 */ + SLE_ADV_DATA_TYPE_SERVICE_STRUCTURE_HASH_VALUE = 0x09, /*!< 服务结构散列值 */ + SLE_ADV_DATA_TYPE_SHORTENED_LOCAL_NAME = 0x0A, /*!< 设备缩写本地名称 */ + SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME = 0x0B, /*!< 设备完整本地名称 */ + SLE_ADV_DATA_TYPE_TX_POWER_LEVEL = 0x0C, /*!< 广播发送功率 */ + SLE_ADV_DATA_TYPE_SLB_COMMUNICATION_DOMAIN = 0x0D, /*!< SLB通信域域名 */ + SLE_ADV_DATA_TYPE_SLB_MEDIA_ACCESS_LAYER_ID = 0x0E, /*!< SLB媒体接入层标识 */ + SLE_ADV_DATA_TYPE_EXTENDED = 0xFE, /*!< 数据类型扩展 */ + SLE_ADV_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF /*!< 厂商自定义信息 */ +} sle_adv_data_type; + + +/** + * @if Eng + * @brief sle adv data config. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle广播数据配置。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +errcode_t sle_uuid_server_adv_init(void); +#endif \ No newline at end of file diff --git a/src/vendor/test/sle_throughput/sle_server_speed/inc/sle_uuid_server.h b/src/vendor/test/sle_throughput/sle_server_speed/inc/sle_uuid_server.h new file mode 100644 index 0000000000000000000000000000000000000000..d95efb299f0fd1901c5f5ce64181207937556f0f --- /dev/null +++ b/src/vendor/test/sle_throughput/sle_server_speed/inc/sle_uuid_server.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) @CompanyNameMagicTag. 2022. All rights reserved. + * + * Description: SLE UUID Server module. + */ + +/** + * @defgroup SLE UUID SERVER API + * @ingroup + * @{ + */ +#ifndef SLE_UUID_SERVER_H +#define SLE_UUID_SERVER_H + +#include "sle_ssap_server.h" + +/* Service UUID */ +#define SLE_UUID_SERVER_SERVICE 0xABCD + +/* Property UUID */ +#define SLE_UUID_SERVER_NTF_REPORT 0x1122 + +/* Property Property */ +#define SLE_UUID_TEST_PROPERTIES (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) + +/* Descriptor Property */ +#define SLE_UUID_TEST_DESCRIPTOR (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) + +/** + * @if Eng + * @brief SLE uuid server inir. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief SLE UUID服务器初始化。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_init(void); + +/** + * @if Eng + * @brief send data to peer device by uuid on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_send_report_by_uuid(uint8_t *data, uint16_t len); + +/** + * @if Eng + * @brief send data to peer device by handle on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_send_report_by_handle(const uint8_t *data, uint8_t len); +#endif diff --git a/src/vendor/test/sle_throughput/sle_server_speed/src/CMakeLists.txt b/src/vendor/test/sle_throughput/sle_server_speed/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..d3ee9908f00f3e950d9a858b703c04f9b18e99a7 --- /dev/null +++ b/src/vendor/test/sle_throughput/sle_server_speed/src/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" + "${CMAKE_CURRENT_SOURCE_DIR}/sle_server_adv.c" + "${CMAKE_CURRENT_SOURCE_DIR}/sle_uuid_server.c" + PARENT_SCOPE) diff --git a/src/vendor/test/sle_throughput/sle_server_speed/src/sle_server_adv.c b/src/vendor/test/sle_throughput/sle_server_speed/src/sle_server_adv.c new file mode 100644 index 0000000000000000000000000000000000000000..12d4811b22d630fe34dd1a06c5e539d247462584 --- /dev/null +++ b/src/vendor/test/sle_throughput/sle_server_speed/src/sle_server_adv.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. + * Description: sle adv config for sle uuid server. + */ +#include "securec.h" +#include "errcode.h" +#include "osal_addr.h" +#include "sle_common.h" +#include "sle_device_discovery.h" +#include "test_suite_uart.h" +#include "sle_connection_manager.h" +#include "sle_errcode.h" +#include "../inc/sle_server_adv.h" + +/* sle device name */ +#define NAME_MAX_LENGTH 15 +/* 连接调度间隔12.5ms,单位125us */ +#define SLE_CONN_INTV_MIN_DEFAULT 0xA +/* 连接调度间隔12.5ms,单位125us */ +#define SLE_CONN_INTV_MAX_DEFAULT 0xA +/* 连接调度间隔25ms,单位125us */ +#define SLE_ADV_INTERVAL_MIN_DEFAULT 0xC8 +/* 连接调度间隔25ms,单位125us */ +#define SLE_ADV_INTERVAL_MAX_DEFAULT 0xC8 +/* 超时时间5000ms,单位10ms */ +#define SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT 0x1F4 +/* 超时时间4990ms,单位10ms */ +#define SLE_CONN_MAX_LATENCY 0x1F3 +/* 广播发送功率 */ +#define SLE_ADV_TX_POWER 10 +/* 广播ID */ +#define SLE_ADV_HANDLE_DEFAULT 1 +/* 最大广播数据长度 */ +#define SLE_ADV_DATA_LEN_MAX 251 + +uint8_t sle_local_name[ NAME_MAX_LENGTH] = "sle_uart_server"; + +#define sample_at_log_print(fmt, args...) test_suite_uart_sendf(fmt, ##args) + +static uint16_t sle_set_adv_local_name(uint8_t *adv_data, uint16_t max_len) +{ + errno_t ret; + uint8_t index = 0; + + uint8_t *local_name = sle_local_name; + uint8_t local_name_len = (uint8_t)strlen((char *)local_name); + for (uint8_t i = 0; i < local_name_len; i++) { + sample_at_log_print("local_name[%d] = 0x%02x\r\n", i, local_name[i]); + } + + adv_data[index++] = local_name_len + 1; + adv_data[index++] = SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME; + ret = memcpy_s(&adv_data[index], max_len - index, local_name, local_name_len); + if (ret != EOK) { + sample_at_log_print("memcpy fail\r\n"); + return 0; + } + return (uint16_t)index + local_name_len; +} + +static uint16_t sle_set_adv_data(uint8_t *adv_data) +{ + size_t len = 0; + uint16_t idx = 0; + errno_t ret = 0; + + len = sizeof(struct sle_adv_common_value); + struct sle_adv_common_value adv_disc_level = { + .length = len - 1, + .type = SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL, + .value = SLE_ANNOUNCE_LEVEL_NORMAL, + }; + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_disc_level, len); + if (ret != EOK) { + sample_at_log_print("adv_disc_level memcpy fail\r\n"); + return 0; + } + idx += len; + + len = sizeof(struct sle_adv_common_value); + struct sle_adv_common_value adv_access_mode = { + .length = len - 1, + .type = SLE_ADV_DATA_TYPE_ACCESS_MODE, + .value = 0, + }; + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_access_mode, len); + if (ret != EOK) { + sample_at_log_print("memcpy fail\r\n"); + return 0; + } + idx += len; + return idx; +} + +static uint16_t sle_set_scan_response_data(uint8_t *scan_rsp_data) +{ + uint16_t idx = 0; + errno_t ret; + size_t scan_rsp_data_len = sizeof(struct sle_adv_common_value); + + struct sle_adv_common_value tx_power_level = { + .length = scan_rsp_data_len - 1, + .type = SLE_ADV_DATA_TYPE_TX_POWER_LEVEL, + .value = SLE_ADV_TX_POWER, + }; + ret = memcpy_s(scan_rsp_data, SLE_ADV_DATA_LEN_MAX, &tx_power_level, scan_rsp_data_len); + if (ret != EOK) { + sample_at_log_print("sle scan response data memcpy fail\r\n"); + return 0; + } + idx += scan_rsp_data_len; + + /* set local name */ + idx += sle_set_adv_local_name(&scan_rsp_data[idx], SLE_ADV_DATA_LEN_MAX - idx); + return idx; +} + +static int sle_set_default_announce_param(void) +{ + sle_announce_param_t param = {0}; + param.announce_mode = SLE_ANNOUNCE_MODE_CONNECTABLE_SCANABLE; + param.announce_handle = SLE_ADV_HANDLE_DEFAULT; + param.announce_gt_role = SLE_ANNOUNCE_ROLE_T_CAN_NEGO; + param.announce_level = SLE_ANNOUNCE_LEVEL_NORMAL; + param.announce_channel_map = SLE_ADV_CHANNEL_MAP_DEFAULT; + param.announce_interval_min = SLE_ADV_INTERVAL_MIN_DEFAULT; + param.announce_interval_max = SLE_ADV_INTERVAL_MAX_DEFAULT; + param.conn_interval_min = SLE_CONN_INTV_MIN_DEFAULT; + param.conn_interval_max = SLE_CONN_INTV_MAX_DEFAULT; + param.conn_max_latency = SLE_CONN_MAX_LATENCY; + param.conn_supervision_timeout = SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT; + return sle_set_announce_param(param.announce_handle, ¶m); +} + +static int sle_set_default_announce_data(void) +{ + errcode_t ret; + uint8_t announce_data_len = 0; + uint8_t seek_data_len = 0; + sle_announce_data_t data = {0}; + uint8_t adv_handle = SLE_ADV_HANDLE_DEFAULT; + uint8_t announce_data[SLE_ADV_DATA_LEN_MAX] = {0}; + uint8_t seek_rsp_data[SLE_ADV_DATA_LEN_MAX] = {0}; + + sample_at_log_print("set adv data default\r\n"); + announce_data_len = sle_set_adv_data(announce_data); + data.announce_data = announce_data; + data.announce_data_len = announce_data_len; + + seek_data_len = sle_set_scan_response_data(seek_rsp_data); + data.seek_rsp_data = seek_rsp_data; + data.seek_rsp_data_len = seek_data_len; + + ret = sle_set_announce_data(adv_handle, &data); + if (ret == ERRCODE_SLE_SUCCESS) { + test_suite_uart_sendf("[SLE DD SDK] set announce data success."); + } else { + test_suite_uart_sendf("[SLE DD SDK] set adv param fail."); + } + return ERRCODE_SLE_SUCCESS; +} + +void sle_announce_enable_cbk(uint32_t announce_id, errcode_t status) +{ + sample_at_log_print("sle announce enable id:%02x, state:%02x\r\n", announce_id, status); +} + +void sle_announce_disable_cbk(uint32_t announce_id, errcode_t status) +{ + sample_at_log_print("sle announce disable id:%02x, state:%02x\r\n", announce_id, status); +} + +void sle_announce_terminal_cbk(uint32_t announce_id) +{ + sample_at_log_print("sle announce terminal id:%02x\r\n", announce_id); +} + +void sle_enable_cbk(errcode_t status) +{ + sample_at_log_print("sle enable status:%02x\r\n", status); +} + +void sle_announce_register_cbks(void) +{ + sle_announce_seek_callbacks_t seek_cbks = {0}; + seek_cbks.announce_enable_cb = sle_announce_enable_cbk; + seek_cbks.announce_disable_cb = sle_announce_disable_cbk; + seek_cbks.announce_terminal_cb = sle_announce_terminal_cbk; + seek_cbks.sle_enable_cb = sle_enable_cbk; + sle_announce_seek_register_callbacks(&seek_cbks); +} + +errcode_t sle_uuid_server_adv_init(void) +{ + sample_at_log_print("sle_uuid_server_adv_init in\r\n"); + + sle_announce_register_cbks(); + sle_set_default_announce_param(); + sle_set_default_announce_data(); + sle_start_announce(SLE_ADV_HANDLE_DEFAULT); + sample_at_log_print("sle_uuid_server_adv_init out\r\n"); + return ERRCODE_SLE_SUCCESS; +} diff --git a/src/vendor/test/sle_throughput/sle_server_speed/src/sle_uuid_server.c b/src/vendor/test/sle_throughput/sle_server_speed/src/sle_uuid_server.c new file mode 100644 index 0000000000000000000000000000000000000000..d30494bdbd6f30f0edf11b99f3505bf5f024027e --- /dev/null +++ b/src/vendor/test/sle_throughput/sle_server_speed/src/sle_uuid_server.c @@ -0,0 +1,388 @@ +/* + * Copyright (c) @CompanyNameMagicTag. 2023. All rights reserved. + * Description: sle uuid server sample. + */ +#include "securec.h" +#include "errcode.h" +#include "osal_addr.h" +#include "sle_common.h" +#include "test_suite_uart.h" +#include "sle_errcode.h" +#include "sle_ssap_server.h" +#include "sle_connection_manager.h" +#include "sle_device_discovery.h" +#include "../inc/sle_uuid_server.h" +#include "../inc/sle_server_adv.h" +#include "app_init.h" +#include "watchdog.h" +#include "soc_osal.h" +#include "tcxo.h" +#include "systick.h" +#include "los_memory.h" + +#define OCTET_BIT_LEN 8 +#define UUID_LEN_2 2 +#define BT_INDEX_4 4 +#define BT_INDEX_5 5 +#define BT_INDEX_0 0 + +#define encode2byte_little(_ptr, data) \ + do { \ + *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 8); \ + *(uint8_t *)(_ptr) = (uint8_t)(data); \ + } while (0) + +/* sle server app uuid for test */ +char g_sle_uuid_app_uuid[UUID_LEN_2] = {0x0, 0x0}; +/* server notify property uuid for test */ +char g_sle_property_value[OCTET_BIT_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +/* sle connect acb handle */ +uint16_t g_sle_conn_hdl = 0; +/* sle server handle */ +uint8_t g_server_id = 0; +/* sle service handle */ +uint16_t g_service_handle = 0; +/* sle ntf property handle */ +uint16_t g_property_handle = 0; + +uint16_t g_sle_paire_state = 0; + +#define sample_at_log_print(fmt, args...) test_suite_uart_sendf(fmt, ##args) + +static uint8_t sle_uuid_base[] = { 0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA, \ + 0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +static void sle_uuid_set_base(sle_uuid_t *out) +{ + (void)memcpy_s(out->uuid, SLE_UUID_LEN, sle_uuid_base, SLE_UUID_LEN); + out->len = UUID_LEN_2; +} + +static void sle_uuid_setu2(uint16_t u2, sle_uuid_t *out) +{ + sle_uuid_set_base(out); + out->len = UUID_LEN_2; + encode2byte_little(&out->uuid[14], u2); +} + +static void ssaps_read_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_read_cb_t *read_cb_para, + errcode_t status) +{ + sample_at_log_print("[uuid server] ssaps read request cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n", + server_id, conn_id, read_cb_para->handle, status); +} + +static void ssaps_write_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para, + errcode_t status) +{ + sample_at_log_print("[uuid server] ssaps write request cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n", + server_id, conn_id, write_cb_para->handle, status); +} + +static void ssaps_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, ssap_exchange_info_t *mtu_size, + errcode_t status) +{ + sample_at_log_print("[uuid server] ssaps write request cbk server_id:%x, conn_id:%x, mtu_size:%x, status:%x\r\n", + server_id, conn_id, mtu_size->mtu_size, status); +} + +static void ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status) +{ + sample_at_log_print("[uuid server] start service cbk server_id:%x, handle:%x, status:%x\r\n", + server_id, handle, status); +} + +static void sle_ssaps_register_cbks(void) +{ + ssaps_callbacks_t ssaps_cbk = {0}; + ssaps_cbk.start_service_cb = ssaps_start_service_cbk; + ssaps_cbk.mtu_changed_cb = ssaps_mtu_changed_cbk; + ssaps_cbk.read_request_cb = ssaps_read_request_cbk; + ssaps_cbk.write_request_cb = ssaps_write_request_cbk; + ssaps_register_callbacks(&ssaps_cbk); +} + +errcode_t sle_uuid_server_send_report_by_handle_id(uint8_t *data, uint8_t len,uint16_t connect_id) +{ + ssaps_ntf_ind_t param = {0}; + param.handle = g_property_handle; + param.type = SSAP_PROPERTY_TYPE_VALUE; + param.value = data; + param.value_len = len; + ssaps_notify_indicate(g_server_id, connect_id, ¶m); + return ERRCODE_SLE_SUCCESS; +} + +#define DATA_LEN 236 +unsigned char data[DATA_LEN]; +extern uint8_t gle_tx_acb_data_num_get(void); +uint64_t count_before_get_us; +uint64_t count_after_get_us; + +void send_data_thread_function(void) +{ + sle_set_data_len(g_sle_conn_hdl, 250); + sle_set_phy_t phy_parm = { + .tx_format = SLE_RADIO_FRAME_2, + .rx_format = SLE_RADIO_FRAME_2, + .tx_phy = 2, + .rx_phy = 2, + .tx_pilot_density = SLE_PHY_PILOT_DENSITY_16_TO_1, + .rx_pilot_density = SLE_PHY_PILOT_DENSITY_16_TO_1, + .g_feedback = 0, + .t_feedback = 0, + }; + sle_set_phy_param(g_sle_conn_hdl, &phy_parm); + sle_set_mcs(g_sle_conn_hdl, 10); + int i = 0; + count_before_get_us = uapi_tcxo_get_us(); + for (int j = 0; j < 20000; j++) { + while (i < 1000) { + if (gle_tx_acb_data_num_get() > 0) { + i++; + data[0] = (i >> 8) & 0xFF; + data[1] = i & 0xFF; + sle_uuid_server_send_report_by_handle_id(data,DATA_LEN, g_sle_conn_hdl); + } + } + i = 0; + LOS_MEM_POOL_STATUS status; + LOS_MemInfoGet(m_aucSysMem0, &status); + printf("[SYS INFO] mem: used:%u, free:%u\r\n", status.uwTotalUsedSize, status.uwTotalFreeSize); + } + count_after_get_us = uapi_tcxo_get_us(); + printf("count_after_get_us = %llu, count_before_get_us = %llu\r\n", count_after_get_us, count_before_get_us); + printf("count_us = %llu\r\n", count_after_get_us - count_before_get_us); + printf("t1:send data thread end\n"); +} + +static errcode_t sle_uuid_server_service_add(void) +{ + errcode_t ret; + sle_uuid_t service_uuid = {0}; + sle_uuid_setu2(SLE_UUID_SERVER_SERVICE, &service_uuid); + ret = ssaps_add_service_sync(g_server_id, &service_uuid, 1, &g_service_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + sample_at_log_print("[uuid server] sle uuid add service fail, ret:%x\r\n", ret); + return ERRCODE_SLE_FAIL; + } + return ERRCODE_SLE_SUCCESS; +} + +static errcode_t sle_uuid_server_property_add(void) +{ + errcode_t ret; + ssaps_property_info_t property = {0}; + ssaps_desc_info_t descriptor = {0}; + uint8_t ntf_value[] = {0x01, 0x0}; + + property.permissions = SLE_UUID_TEST_PROPERTIES; + sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, &property.uuid); + property.value = osal_vmalloc(sizeof(g_sle_property_value)); + if (property.value == NULL) { + sample_at_log_print("[uuid server] sle property mem fail\r\n"); + return ERRCODE_SLE_FAIL; + } + if (memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value, + sizeof(g_sle_property_value)) != EOK) { + osal_vfree(property.value); + sample_at_log_print("[uuid server] sle property mem cpy fail\r\n"); + return ERRCODE_SLE_FAIL; + } + ret = ssaps_add_property_sync(g_server_id, g_service_handle, &property, &g_property_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + sample_at_log_print("[uuid server] sle uuid add property fail, ret:%x\r\n", ret); + osal_vfree(property.value); + return ERRCODE_SLE_FAIL; + } + descriptor.permissions = SLE_UUID_TEST_DESCRIPTOR; + descriptor.value = osal_vmalloc(sizeof(ntf_value)); + if (descriptor.value == NULL) { + sample_at_log_print("[uuid server] sle descriptor mem fail\r\n"); + osal_vfree(property.value); + return ERRCODE_SLE_FAIL; + } + if (memcpy_s(descriptor.value, sizeof(ntf_value), ntf_value, sizeof(ntf_value)) != EOK) { + sample_at_log_print("[uuid server] sle descriptor mem cpy fail\r\n"); + osal_vfree(property.value); + osal_vfree(descriptor.value); + return ERRCODE_SLE_FAIL; + } + ret = ssaps_add_descriptor_sync(g_server_id, g_service_handle, g_property_handle, &descriptor); + if (ret != ERRCODE_SLE_SUCCESS) { + sample_at_log_print("[uuid server] sle uuid add descriptor fail, ret:%x\r\n", ret); + osal_vfree(property.value); + osal_vfree(descriptor.value); + return ERRCODE_SLE_FAIL; + } + osal_vfree(property.value); + osal_vfree(descriptor.value); + return ERRCODE_SLE_SUCCESS; +} + +static errcode_t sle_uuid_server_add(void) +{ + errcode_t ret; + sle_uuid_t app_uuid = {0}; + + sample_at_log_print("[uuid server] sle uuid add service in\r\n"); + app_uuid.len = sizeof(g_sle_uuid_app_uuid); + if (memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)) != EOK) { + return ERRCODE_SLE_FAIL; + } + ssaps_register_server(&app_uuid, &g_server_id); + + if (sle_uuid_server_service_add() != ERRCODE_SLE_SUCCESS) { + ssaps_unregister_server(g_server_id); + return ERRCODE_SLE_FAIL; + } + + if (sle_uuid_server_property_add() != ERRCODE_SLE_SUCCESS) { + ssaps_unregister_server(g_server_id); + return ERRCODE_SLE_FAIL; + } + sample_at_log_print("[uuid server] sle uuid add service, server_id:%x, service_handle:%x, property_handle:%x\r\n", + g_server_id, g_service_handle, g_property_handle); + ret = ssaps_start_service(g_server_id, g_service_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + sample_at_log_print("[uuid server] sle uuid add service fail, ret:%x\r\n", ret); + return ERRCODE_SLE_FAIL; + } + sample_at_log_print("[uuid server] sle uuid add service out\r\n"); + return ERRCODE_SLE_SUCCESS; +} + +static void sle_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr, + sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) +{ + sample_at_log_print("[uuid server] connect state changed conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, \ + disc_reason:0x%x\r\n", conn_id, conn_state, pair_state, disc_reason); + sample_at_log_print("[uuid server] connect state changed addr:%02x:**:**:**:%02x:%02x\r\n", + addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); + g_sle_conn_hdl = conn_id; + sle_connection_param_update_t parame = {0}; + parame.conn_id = conn_id; + parame.interval_min = 0xA; + parame.interval_max = 0xA; //18.75ms + parame.max_latency = 0; + parame.supervision_timeout = 0x1f4; + if (conn_state == SLE_ACB_STATE_CONNECTED) { + sle_update_connect_param(¶me); + } +} + +static void sle_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + sample_at_log_print("[uuid server] pair complete conn_id:%02x, status:%x\r\n", + conn_id, status); + sample_at_log_print("[uuid server] pair complete addr:%02x:**:**:**:%02x:%02x\r\n", + addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); + sle_pair_state_t pair_state; + sle_get_pair_state(addr, &pair_state); + printf("pair_state:0x%x\r\n", pair_state); + if (pair_state == SLE_PAIR_PAIRED) { + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)send_data_thread_function, 0, "RadarTask", 0x2000); + osal_kthread_set_priority(task_handle, 25); + if (task_handle != NULL) { + osal_kfree(task_handle); + } + osal_kthread_unlock(); + } + printf("kthread success\r\n"); +} + +void sle_sample_update_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_evt_t *param) +{ + test_suite_uart_sendf("[ssap server] updat state changed conn_id:%d, interval = %02x\n", conn_id, param->interval); + if (status == 0) { + } +} + +void sle_sample_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param) +{ + test_suite_uart_sendf("[ssap server] updat req state changed conn_id:%d, interval_min = %02x, interval_max = %02x\n", conn_id, param->interval_min, param->interval_max); + if (status == 0) { + } +} + +void sle_sample_rssi_cbk(uint16_t conn_id, int8_t rssi, errcode_t status) +{ + test_suite_uart_sendf("[ssap server] conn_id:%d, rssi = %c, status = %x\n", conn_id, rssi, status); +} + +static void sle_conn_register_cbks(void) +{ + sle_connection_callbacks_t conn_cbks = {0}; + conn_cbks.connect_state_changed_cb = sle_connect_state_changed_cbk; + conn_cbks.pair_complete_cb = sle_pair_complete_cbk; + conn_cbks.connect_param_update_req_cb = sle_sample_update_req_cbk; + conn_cbks.connect_param_update_cb = sle_sample_update_cbk; + conn_cbks.read_rssi_cb = sle_sample_rssi_cbk; + sle_connection_register_callbacks(&conn_cbks); +} + +void sle_ssaps_set_info(void) +{ + ssap_exchange_info_t info = {0}; + info.mtu_size = 250; + info.version = 1; + ssaps_set_info(g_server_id, &info); +} + +void sle_connect(void) +{ + sle_default_connect_param_t param = {0}; + param.enable_filter_policy = 0; + param.gt_negotiate = 0; + param.initiate_phys = 1; + param.max_interval = 0xa; + param.min_interval = 0xa; + param.scan_interval = 400; + param.scan_window = 20; + param.timeout = 0x1fc; + sle_default_connection_param_set(¶m); +} + +/* 初始化uuid server */ +errcode_t sle_uuid_server_init(void) +{ + uapi_watchdog_disable(); + enable_sle(); + sle_ssaps_set_info(); + printf("sle enable\r\n"); + sle_conn_register_cbks(); + sle_ssaps_register_cbks(); + sle_uuid_server_add(); + sle_uuid_server_adv_init(); + sle_connect(); + sample_at_log_print("[uuid server] init ok\r\n"); + return ERRCODE_SLE_SUCCESS; +} + +int sle_speed_init(void) +{ + for(int i=0;i + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + +​ 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + +​ 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + +​ 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + +​ 任务1每1S打印一次“This is Thread1----”,任务二每500ms打印一次“This is Thread2----。 + + ![image-20240418110736915](../../../docs/pic/thread/image-20240418110736915.png) + +## 1.4 接口介绍 + +### 1.4.1 osal_kthread_lock() + +| **定义:** | void osal_kthread_lock(void); | +| ------------ | ---------------------------------------- | +| **功能:** | 禁止系统任务调度 | +| **参数:** | void类型 | +| **返回值:** | 无 | +| **依赖:** | kernel\osal\include\schedule\osal_task.h | + +### 1.4.2 osal_kthread_create() + +| 定义: | osal_task *osal_kthread_create(osal_kthread_handler handler, void *data, const char *name, unsigned int stack_size); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 创建任务 | +| **参数:** | handler:线程要处理的函数
data:函数处理程序数据
name:显示的线程名称
stack_size:线程堆栈空间的大小 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | kernel\osal\include\schedule\osal_task.h | + +### 1.4.3 osal_kthread_set_priority() + +| **定义:** | int osal_kthread_set_priority(osal_task *task, unsigned int priority); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置任务优先级 | +| **参数:** | task:要排定优先级的线程
priority:要设定的优先级 | +| **返回值:** | OSAL_SUCCESS:成功 OSAL_FAILURE:失败 | +| **依赖:** | kernel\osal\include\schedule\osal_task.h | + +### 1.4.4 osal_kthread_unlock() + +| **定义:** | void osal_kthread_unlock(void); | +| ------------ | ---------------------------------------- | +| **功能:** | 允许系统任务调度 | +| **参数:** | void | +| **返回值:** | 无 | +| **依赖:** | kernel\osal\include\schedule\osal_task.h | + +## 1.5 具体实现 + + 步骤一:在open_cfbb\src\kernel\liteos\liteos_v208.5.0\Huawei_LiteOS\.config中配置任务数,默认为20,配置LOSCFG_BASE_CORE_TSK_LIMIT系统支持最大任务数需要根据用户需求配置; + + 步骤二:锁任务osal_kthread_lock,锁住任务,防止高优先级任务调度; + + 步骤三:创建任务osThreadNew; + + 步骤四:运行任务app_run(),代码总入口; + + 步骤五:解锁任务osal_kthread_unlock,让任务按照优先级进行调度; + +## 1.6 案例实现 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”thread“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hisilicon\thread文件里面内容“CMakeList.txt”、“thread_example.c”拷贝到**步骤一创建的Sample文件夹中”thread“**下。 + +![image-20240229141239873](../../../docs/pic/thread/image-20240229141239873.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support THREAD Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240229141207010 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七:软件烧录成功后,按一下开发板的RESET按键复位开发板,烧录完成后,任务1每1S打印一次“This is Thread1----”,任务二每500ms打印一次“This is Thread2。串口打印信息如下。 + + ![image-20240418110732610](../../../docs/pic/thread/image-20240418110732610.png) \ No newline at end of file diff --git a/src/vendor/test/thread/thread_example.c b/src/vendor/test/thread/thread_example.c new file mode 100644 index 0000000000000000000000000000000000000000..868d20cd7cb4dee59fe6ff28e522af4d3415cd3c --- /dev/null +++ b/src/vendor/test/thread/thread_example.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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 "pinctrl.h" +#include "osal_debug.h" +#include "common_def.h" +#include "soc_osal.h" +#include "app_init.h" + +#define TASKS_TEST_TASK_STACK_SIZE 0x1000 +#define TASKS_TEST_TASK1_PRIO (osPriority_t)(17) +#define TASKS_TEST_TASK2_PRIO (osPriority_t)(18) +#define THREAD_DELAY_1S 100 +#define THREAD_DELAY_500MS 50 + +/** + * @brief Thread1 entry + * + */ +void Thread1(void) +{ + int sum = 0; + + while (1) { + printf("This is Thread1----%d\n", sum++); + osDelay(THREAD_DELAY_1S); + } +} + +/** + * @brief Thread2 entry + * + */ +void Thread2(void) +{ + int sum = 0; + + while (1) { + printf("This is Thread2----%d\n", sum++); + osDelay(THREAD_DELAY_500MS); + } +} + +/** + * @brief Main Entry of the Thread Example + * + */ +static void ThreadExample(void) +{ + int32_t ret = 0; + osal_task *example_task1_info, *example_task2_info; + osal_kthread_lock(); + // 创建任务1 + example_task1_info = + osal_kthread_create((osal_kthread_handler)Thread1, NULL, "example_task1", TASKS_TEST_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(example_task1_info, TASKS_TEST_TASK1_PRIO); + if (ret != OSAL_SUCCESS) { + printf("example_task creat failed\r\n"); + } + example_task2_info = + osal_kthread_create((osal_kthread_handler)Thread2, NULL, "example_task2", TASKS_TEST_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(example_task2_info, TASKS_TEST_TASK2_PRIO); + if (ret != OSAL_SUCCESS) { + printf("example_task creat failed\r\n"); + } + osal_kthread_unlock(); +} + +app_run(ThreadExample); diff --git a/src/vendor/test/timer/CMakeLists.txt b/src/vendor/test/timer/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..46f4b6a73b0e67d545a966e75e249beb7cb03c63 --- /dev/null +++ b/src/vendor/test/timer/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/timer_example.c" PARENT_SCOPE) diff --git a/src/vendor/test/timer/README.md b/src/vendor/test/timer/README.md new file mode 100644 index 0000000000000000000000000000000000000000..93950cc733e998f3a2859cac25109570f056df2e --- /dev/null +++ b/src/vendor/test/timer/README.md @@ -0,0 +1,132 @@ +# timer + +## 1.1 介绍 + +**功能介绍:** 本实验内容实现了创建两个软件定时器,实现了软件定时器创建、启动、单次软件定时器、周期软件定时器等使用方法。单次软件定时器在启动后只会触发一次定时器事件,周期软件定时器会周期性的触发定时器事件,直到手动停止定时器或者触发其他软件条件,否则永远执行。 + +**软件概述:** 软件定时器是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数。定时精度与系统Tick时钟的周期有关。 + +**硬件概述:** 核心板。硬件搭建要求如图所示。 + + image-20240226173007100 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + +​ 本示例支持开发板:HiHope_NearLink_DK3863E_V00 + +### 1.2.2 支持API版本、SDK版本 + +​ 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + +​ 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + +​ 任务1过1S只执行一次定时器中断,任务2每隔2S执行一次定时器中断 + + ![image-20240401140549325](../../../docs/pic/timer/image-20240401140549325.png) + +## 1.4 接口介绍 + +#### 1.4.1 uapi_time_init() + +| **定义:** | errcode uapi_time_init(void); | +| ------------ | --------------------------------- | +| **功能:** | 初始化定时器 | +| **参数:** | void类型 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\time.h | + +#### 1.4.2 uapi_timer_create() + +| 定义: | errcode_t uapi_timer_create(timer_index_t index, timer_handle_t *timer); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 创建软件定时器 | +| **参数:** | index:硬件定时器索引
timer:定时器处理返回值。 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\time.h | + +#### 1.4.3 uapi_timer_start() + +| **定义:** | errcode_t uapi_timer_start(timer_handle_t timer, uint32_t time_us, timer_callback_t callback, uintptr_t data); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 启动软件定时器,定时器超时时间(单位:ms) | +| **参数:** | timer:创建的定时器
time_us:定时器超时时间
callback:定时器回调函数
data:定时器参数,用于传递给定时器回调函数 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\time.h | + +#### 1.4.4 uapi_timer_adapter() + +| **定义:** | errcode_t uapi_timer_adapter(timer_index_t index, uint32_t int_id, uint16_t int_priority); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 适配定时器 | +| **参数:** | index:硬件定时器索引
int_id:硬件定时器中断ID
int_priority:硬件定时器中断优先级 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | iinclude\driver\time.h | + +#### 1.4.5 uapi_timer_deinit() + +| **定义:** | errcode_t uapi_timer_deinit(void); | +| ------------ | ---------------------------------- | +| **功能:** | 去初始化定时器 | +| **参数:** | void类型 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | iinclude\driver\time.h | + +#### 1.4.6 uapi_timer_stop() + +| **定义:** | errcode_t uapi_timer_stop(timer_handle_t timer); | +| ------------ | ------------------------------------------------ | +| **功能:** | 停止软件定时器 | +| **参数:** | timer:uapi_timer_create 创建的定时器 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | iinclude\driver\time.h | + +#### 1.4.7 uapi_timer_delete() + +| **定义:** | errcode_t uapi_timer_delete(timer_handle_t timer); | +| ------------ | -------------------------------------------------- | +| **功能:** | 删除定时器 | +| **参数:** | timer:创建的定时器 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | iinclude\driver\time.h | + +## 1.5 具体实现 + + 步骤一:初始化软件定时器,并创建两个软件定时器uapi_timer_create(); + + 步骤二:分别启动单次软件定时器、周期软件定时器的启动 + +## 1.6 案例实现 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”timer“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\timer文件里面内容“CMakeList.txt”、“timer_example.c”拷贝到**步骤一创建的Sample文件夹中”timer“**下。 + + ![image-20240401114124681](../../../docs/pic/timer/image-20240401114124681.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support THREAD Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240401113155332 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七:软件烧录成功后,按一下开发板的RESET按键复位开发板,烧录完成后,串口打印信息如下。 + + ![image-20240401140549325](../../../docs/pic/timer/image-20240401140549325.png) diff --git a/src/vendor/test/timer/timer_example.c b/src/vendor/test/timer/timer_example.c new file mode 100644 index 0000000000000000000000000000000000000000..f5b310931e005f01d5d466f302078d0b06c3cf63 --- /dev/null +++ b/src/vendor/test/timer/timer_example.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., LIMITED. + * 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 "pinctrl.h" +#include "common_def.h" +#include "soc_osal.h" +#include "timer.h" +#include "osal_debug.h" +#include "app_init.h" +#include "tcxo.h" +#include "chip_core_irq.h" + +#define TIMER_TASK_STACK_SIZE 0x1000 +#define TIMER_TASK_PRIO 17 // 任务的优先级,数值越小优先级越高 +#define TIMER_TIMERS_NUM 2 +#define TIMER_INDEX 1 +#define TIMER_PRIO 1 +#define TIMER_DELAY_INT 5 +#define TIMER1_DELAY_1S 1000000 // 延时1s +#define TIMER2_DELAY_2S 2000000 // 延时2s + +timer_handle_t timer_index[TIMER_TIMERS_NUM] = {0}; +typedef struct timer_info { + uint32_t start_time; + uint32_t end_time; + uint32_t delay_time; +} timer_info_t; + +static timer_info_t g_timers_info[TIMER_TIMERS_NUM] = {{0, 0, TIMER1_DELAY_1S}, {0, 0, TIMER2_DELAY_2S}}; + +/** + * @brief Callback for Timer1 triggering + * + */ +void Timer1Callback(uintptr_t data) +{ + uint32_t timer = (uint32_t)data; + g_timers_info[timer].end_time = uapi_tcxo_get_ms(); + osal_printk("This is Timer1Callback real time = %dms\r\n", // 单定时器 + (g_timers_info[0].end_time - g_timers_info[0].start_time)); +} + +/** + * @brief Callback for Timer2 triggering + * + */ +void Timer2Callback(uintptr_t data) +{ + uint32_t timer = (uint32_t)data; + g_timers_info[timer].end_time = uapi_tcxo_get_ms(); + osal_printk("This is Timer2Callback real time = %dms\r\n", + (g_timers_info[1].end_time - g_timers_info[1].start_time)); + g_timers_info[1].start_time = g_timers_info[1].end_time; + uapi_timer_start(timer_index[1], g_timers_info[1].delay_time, Timer2Callback, 1); // 周期定时器 +} + +/** + * @brief Main Entry of the Timer Example + * + */ +static void *timer_task(const char *arg) +{ + unused(arg); + uapi_timer_init(); + uapi_timer_adapter(TIMER_INDEX, TIMER_1_IRQN, TIMER_PRIO); + // 创建单次软件定时,1s + uapi_timer_create(TIMER_INDEX, &timer_index[0]); + g_timers_info[0].start_time = uapi_tcxo_get_ms(); + uapi_timer_start(timer_index[0], g_timers_info[0].delay_time, Timer1Callback, 0); // 0代表定时器参数,用于传递给定时器回调函数 + // 创建周期性软件定时,2s + uapi_timer_create(TIMER_INDEX, &timer_index[1]); + g_timers_info[1].start_time = uapi_tcxo_get_ms(); + uapi_timer_start(timer_index[1], g_timers_info[1].delay_time, Timer2Callback, 1); // 1代表定时器参数,用于传递给定时器回调函数 + return NULL; +} + +static void timer_entry(void) +{ + uint32_t ret; + osal_task *taskid; + // 创建任务调度 + osal_kthread_lock(); + // 创建任务1 + taskid = osal_kthread_create((osal_kthread_handler)timer_task, NULL, "timer_task", + TIMER_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid, TIMER_TASK_PRIO); + if (ret != OSAL_SUCCESS) { + printf("create task failed .\n"); + } +} +/* Run the timer_entry. */ +app_run(timer_entry); \ No newline at end of file diff --git a/src/vendor/test/trafficlight/CMakeLists.txt b/src/vendor/test/trafficlight/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..489dcbee40250b06e37d40733700922b6f04f418 --- /dev/null +++ b/src/vendor/test/trafficlight/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/gpio_led_pwm_demo.c" PARENT_SCOPE) diff --git a/src/vendor/test/trafficlight/README.md b/src/vendor/test/trafficlight/README.md new file mode 100644 index 0000000000000000000000000000000000000000..333a52bdc0f348e95d0e3eb7ddb82011d72a8184 --- /dev/null +++ b/src/vendor/test/trafficlight/README.md @@ -0,0 +1,150 @@ +## trafficlight + +## 1.1 介绍 + +**功能介绍:** 交通灯板上红、黄、绿三种颜色灯闪烁,同时按键可以控制蜂鸣器鸣响。 + +**软件概述:** GPIO引脚输出高低电平状态。 + +**硬件概述:** 核心板、交通灯板。通过交通灯板上丝印可以看出是RED与底板的D10相连,底板左边位置D10对应核心板上GPIO 7,GREEN与底板的A11相连,底板左边位置A11对应核心板上GPIO 11,YELLOW与底板的A12相连,底板左边位置A12对应核心板上GPIO 12,Switch与底板的MOSI相连,底板左边位置MOSI对应核心板上GPIO14,蜂鸣器BEEP与底板的A9相连,底板左边A9对应核心板GPIO 9。硬件搭建要求如图所示: + + 参考[核心板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf)、[交通灯板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_SSL_VER.A.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf) + + image-20240415144302434 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 交通灯板上红、黄、绿三种颜色灯闪烁,同时按键可以控制蜂鸣器鸣响。 + + image-20240418152820982 + +## 1.4 接口介绍 + +### 1.4.1 uapi_pwm_init() + +| **定义:** | errcode_t uapi_pwm_init (void) | +| ------------ | --------------------------------- | +| **功能:** | 初始化PWM。 | +| **参数:** | 无 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pwm.h | + +### 1.4.2 uapi_pwm_open() + +| 定义: | errcode_t uapi_pwm_open(uint8_t channel, const pwm_config_t *cfg); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 打开具有指定配置的PWM设备 | +| **参数:** | channel :使用的PWM设备
cfg :PWM设备的配置信息 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pwm.h | + +### 1.4.3 uapi_pwm_set_group() + +| **定义:** | errcode_t uapi_pwm_set_group(uint8_t group, uint16_t channel_id); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 根据指定的参数初始化该i2c为主机 | +| **参数:** | group: PWM组
channel_id: 分配到同一个组里的所有通道id,channel_id中的每一位bit对应相对应的一个通道 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pwm.h | + +### 1.4.4 uapi_pwm_start() + +| **定义:** | errcode_t uapi_pwm_start(uint8_t channel); | +| ------------ | ------------------------------------------ | +| **功能:** | 开始PWM | +| **参数:** | channel :使用的PWM设备 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pwm.h | + +### 1.4.5 uapi_pwm_close() + +| **定义:** | errcode_t uapi_pwm_close(uint8_t channel); | +| ------------ | ------------------------------------------ | +| **功能:** | 关闭指定的PWM。 | +| **参数:** | channel :使用的PWM设备。 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pwm.h | + +### 1.4.6 uapi_pin_set_mode() + +| **定义:** | errcode_t uapi_pin_set_mode(pin_t pin, pin_mode_t mode); | +| ------------ | -------------------------------------------------------- | +| **功能:** | 设置引脚复用模式 | +| **参数:** | pin:io
mode:复用模式 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pinctrl.h | + +### 1.4.7 uapi_gpio_set_dir() + +| **定义:** | errcode_t uapi_gpio_set_dir(pin_t pin, gpio_direction_t dir); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置GPIO的输入输出方向 | +| **参数:** | pin:io
dir:输入输出方向 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +### 1.4.8 uapi_gpio_register_isr_func() + +| **定义:** | errcode_t uapi_gpio_register_isr_func(pin_t pin, uint32_t trigger, gpio_callback_t callback); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 注册GPIO的中断 | +| **参数:** | pin:io
trigger: GPIO中断类型: 1 : 上升沿中断 2 : 下降沿中断 3 : 双边沿中断 4 : 低电平中断 8 : 高电平中断
callback 指向回调的指针 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +## 1.5 具体实现 + + 步骤一:设置GPIO为输出模式; + + 步骤二:初始化PWM,配置PWM参数; + + 步骤三:设置GPIO输出为高或低; + + 步骤四:打开指定PWM设备; + + 步骤五:翻转输出GPIO电平状态 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”trafficlight“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\traffic_demo文件里面内容拷贝到**步骤一创建的Sample文件夹中”trafficlight“**。 + +![image-20240418152414639](../../../docs/pic/trafficlight/image-20240418152414639.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support TRAFFICLIGHT Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240418152441142 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七:软件烧录成功后,按一下开发板的RESET按键复位开发板,烧录完成后,板上灯闪烁,通过按键控制蜂鸣器鸣响。 + + + image-20240418152820982 \ No newline at end of file diff --git a/src/vendor/test/trafficlight/gpio_led_pwm_demo.c b/src/vendor/test/trafficlight/gpio_led_pwm_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..6339f6f7a8ebd38f3771f0d1946eb9cd30e3fb2b --- /dev/null +++ b/src/vendor/test/trafficlight/gpio_led_pwm_demo.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "gpio.h" +#include "hal_gpio.h" +#include "watchdog.h" +#include "pwm.h" +#include "test_suite_log.h" +#include "soc_osal.h" +#include "app_init.h" + +#define BLINKY_TASK_STACK_SIZE 0x2000 +#define CONFIG_BLINKY_DURATION_MS 10 +#define BLINKY_TASK_PRIO 17 +#define CONFIG_GPIO14_PIN 14 // 按键 +#define CONFIG_GPIO9_PIN 9 // 蜂鸣器 +#define CONFIG_GPIO7_PIN 7 // RED +#define CONFIG_GPIO11_PIN 11 // GREEN +#define CONFIG_GPIO10_PIN 10 // YELLOW +#define PWM1_CHANNEL 1 +#define CONFIG_PWM_PIN_MODE 1 +#define PWM0_GROUP_ID 1 +static int g_beepState = 0; + +static void gpio_callback_func(pin_t pin, uintptr_t param) +{ + UNUSED(pin); + UNUSED(param); + g_beepState = !g_beepState; + printf("Button pressed.\r\n"); +} + +void gpio_set_value(pin_t pin) +{ + uapi_pin_set_mode(pin, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(pin, GPIO_DIRECTION_OUTPUT); + uapi_gpio_set_val(pin, GPIO_LEVEL_LOW); +} + +static void *beep_led_task(const char *arg) +{ + unused(arg); + pwm_config_t cfg_no_repeat = {20000, 10000, 0xFF, 0xFF, false}; + uapi_pin_set_mode(CONFIG_GPIO9_PIN, CONFIG_PWM_PIN_MODE); + gpio_set_value(CONFIG_GPIO7_PIN); + gpio_set_value(CONFIG_GPIO11_PIN); + gpio_set_value(CONFIG_GPIO10_PIN); + uapi_pin_set_mode(CONFIG_GPIO14_PIN, HAL_PIO_FUNC_GPIO); + gpio_select_core(CONFIG_GPIO14_PIN, CORES_APPS_CORE); + uapi_gpio_set_dir(CONFIG_GPIO14_PIN, GPIO_DIRECTION_INPUT); + errcode_t ret = uapi_gpio_register_isr_func(CONFIG_GPIO14_PIN, GPIO_INTERRUPT_FALLING_EDGE, gpio_callback_func); + if (ret != 0) { + uapi_gpio_unregister_isr_func(CONFIG_GPIO14_PIN); + } + while (1) { + uapi_watchdog_kick(); // 防止系统挂失 + osal_mdelay(CONFIG_BLINKY_DURATION_MS); + uapi_gpio_toggle(CONFIG_GPIO7_PIN); + uapi_gpio_toggle(CONFIG_GPIO11_PIN); + uapi_gpio_toggle(CONFIG_GPIO10_PIN); + if (g_beepState) { + uapi_pwm_init(); + uapi_pwm_open(PWM1_CHANNEL, &cfg_no_repeat); + uapi_pwm_set_group(PWM0_GROUP_ID, 1 << PWM1_CHANNEL); // 一个bit一个pwm通路,8路全是11111111 + uapi_pwm_start(PWM0_GROUP_ID); + } else { + uapi_pwm_close(PWM1_CHANNEL); + uapi_pwm_deinit(); + } + } + return NULL; +} + +static void beep_led_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)beep_led_task, 0, "BeepLedTask", BLINKY_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, BLINKY_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the blinky_entry. */ +app_run(beep_led_entry); \ No newline at end of file diff --git a/src/vendor/test/tricolored/CMakeLists.txt b/src/vendor/test/tricolored/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ba0eb2fa187064de68096e8528a31d68a8dc89cc --- /dev/null +++ b/src/vendor/test/tricolored/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/tricolored_sample.c" PARENT_SCOPE) diff --git a/src/vendor/test/tricolored/README.md b/src/vendor/test/tricolored/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5ba4f9817bb50f58fd35b02897fce76c72ff9fa8 --- /dev/null +++ b/src/vendor/test/tricolored/README.md @@ -0,0 +1,102 @@ +# tricolored + +## 1.1 介绍 + +**功能介绍:** 通过一个GPIO口控制核心板上SK6812亮绿、红、蓝三色灯。 + +**软件概述:** 通过GPIO模拟电平高低实现发送不同数据码,控制外设亮不同颜色。 + +**硬件概述:** 核心板。通过原理图可以看出SK6812 DI脚与核心板GPIO 5相连。SK6812数据手册:https://gitee.com/HiSpark/hi3861_hdu_iot_application/issues/I6WPSS?from=project-issue 里面的SK6812 MINI。硬件搭建要求如图所示: + + 参考[核心板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf) + + image-20240415144302434 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 通过一个GPIO口控制核心板上SK6812亮绿、红、蓝三色灯。 + + image-20240418171054830 + +## 1.4 接口介绍 + +### 1.4.1 uapi_reg_setbit() + +| **定义:** | uapi_reg_setbit(addr, val) | +| ------------ | ----------------------------------- | +| **功能:** | 设置GPIO的高低电平 | +| **参数:** | pin: io引脚
dir:输入输出方向 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\common_def.h | + +### 1.4.2 uapi_tcxo_delay_count() + +| 定义: | errcode_t uapi_tcxo_delay_count(uint64_t ticks_delay) | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 延时ticks | +| **参数:** | ticks_delay:延时ticks ,延时time = ticks_delay * (1 / 32000000) | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | extern errcode_t uapi_tcxo_delay_count(uint16_t ticks_delay); | + +### 1.4.3 uapi_reg_read32() + +| **定义:** | uapi_reg_read32(addr, val) | +| ------------ | ---------------------------------- | +| **功能:** | 读取GPIO电平值 | +| **参数:** | pin:io引脚 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\common_def.h | + +## 1.5 具体实现 + + 步骤一:设置GPIO为输出模式。 + + 步骤二:设置GPIO输出为高或低。 + + 步骤三:通过uapi_tcxo_delay_count设置延时,模拟1码,0码数据。 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”tricolored“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\tricolored文件里面内容拷贝到**步骤一创建的Sample文件夹中”tricolored“**。 + + ![image-20240418170746645](../../../docs/pic/tricolored/image-20240418170746645.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support LED Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240418170817541 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七“软件烧录成功后,按一下开发板的RESET按键复位开发板, 通过一个GPIO口控制核心板上SK6812亮绿、红、蓝三色灯。 + + image-20240418171054830 + + \ No newline at end of file diff --git a/src/vendor/test/tricolored/tricolored_sample.c b/src/vendor/test/tricolored/tricolored_sample.c new file mode 100644 index 0000000000000000000000000000000000000000..e5cab1d0360ecb5ca68c265f7752c77b5bb9179b --- /dev/null +++ b/src/vendor/test/tricolored/tricolored_sample.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "watchdog.h" +#include "tcxo.h" +#include "gpio.h" +#include "soc_osal.h" +#include "app_init.h" + +#define TRICOLORED_TASK_PRIO 24 +#define TRICOLORED_TASK_STACK_SIZE 0x1000 +#define BSP_LED_0 5 +#define BSP_LED_MODE 4 + +extern errcode_t uapi_tcxo_delay_count(uint16_t ticks_delay); + +void one_num(void) +{ + uapi_reg_setbit(0x44028030, 5); // 0x44028030代表GPIO电平拉高寄存器,5代表GPIO5,将gpio5拉高,可以参考platform_core.h + uapi_tcxo_delay_count(8); + uapi_reg_setbit(0x44028034, 5); // 0x44028034代表GPIO电平拉低寄存器,5代表GPIO5,将gpio5拉低,可以参考platform_core.h + uapi_tcxo_delay_us(2); +} + +void zero_num(void) +{ + uint32_t preg = 0; + preg = preg; + uapi_reg_setbit(0x44028030, 5); + for (int i = 0; i < 7; i++) { + // 由于uapi_tcxo_delay_us在低于1us以后,延时不准确,通过测试发现读一次寄存器大概50ns + uapi_reg_read32(0x44028030, preg); + } + uapi_reg_setbit(0x44028034, 5); + uapi_tcxo_delay_us(2); +} + +void green_led(void) +{ + for (int i = 0; i < 8; i++) { + one_num(); + } + for (int i = 0; i < 8; i++) { + zero_num(); + } + for (int i = 0; i < 8; i++) { + zero_num(); + } +} + +void red_led(void) +{ + for (int i = 0; i < 8; i++) { + zero_num(); + } + for (int i = 0; i < 8; i++) { + one_num(); + } + for (int i = 0; i < 8; i++) { + zero_num(); + } +} + +void blue_led(void) +{ + for (int i = 0; i < 8; i++) { + zero_num(); + } + for (int i = 0; i < 8; i++) { + zero_num(); + } + for (int i = 0; i < 8; i++) { + one_num(); + } +} + +static int tricolored_task(const char *arg) +{ + UNUSED(arg); + uapi_pin_set_mode(BSP_LED_0, BSP_LED_MODE); + uapi_gpio_set_dir(BSP_LED_0, GPIO_DIRECTION_OUTPUT); + uapi_reg_setbit(0x44028034, 5); + uapi_tcxo_delay_us(100); // 初始化三色灯,等待三色灯正常工作,延时需要大于80us,可以参考三色灯规格书 + green_led(); + uapi_tcxo_delay_ms(200); + red_led(); + osal_mdelay(200); + blue_led(); + return 0; +} + +static void blinky_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)tricolored_task, 0, "TricoloredTask", TRICOLORED_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, TRICOLORED_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the blinky_entry. */ +app_run(blinky_entry); \ No newline at end of file diff --git a/src/vendor/test/uartdemo/CMakeLists.txt b/src/vendor/test/uartdemo/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e618a7502548f7c9d3d80e741ebfac7ab0ef4556 --- /dev/null +++ b/src/vendor/test/uartdemo/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/uart_demo.c" PARENT_SCOPE) \ No newline at end of file diff --git a/src/vendor/test/uartdemo/README.md b/src/vendor/test/uartdemo/README.md new file mode 100644 index 0000000000000000000000000000000000000000..422bab59135ba07ce3e02981859c5c6879091e8e --- /dev/null +++ b/src/vendor/test/uartdemo/README.md @@ -0,0 +1,141 @@ +## uartdemo + +## 1.1 介绍 + +**功能介绍:** 本实验GPIO 15,GPIO 16复用为UART功能,板端TX与RX通过跳线帽连接,实现轮询方式数据的发送与接收和中断方式数据接收与发送。 + +**软件概述:** GPIO引脚输出高低电平状态。 + +**硬件概述:** 核心板、底板。核心板主板插在底板上,查看底板左侧,通过查看主板丝印核心板TXD1对应底板TX,在底板右侧寻找TX硬件接口,使用杜邦线(跳线帽)将TX与RX相连,核心板主板插在底板上,查看底板左侧,通过查看主板丝印核心板RXD1对应底板RX,在底板右侧寻找RX硬件接口,使用杜邦线(跳线帽)将TX与RX相连。一般情况下两块UART设备(A和B)通信,硬件接线方式为A板TX接B板RX,A板RX接B板TX,这里由于硬件数量有限,使用一块单板验证,单板的TX与RX通过杜邦线或者跳线帽相连。硬件搭建要求如图所示: + + 参考[核心板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf) + + image-20240418162118123 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 每隔5S串口循环打印“hello uart1”。 + +![image-20240418163011967](../../../docs/pic/uartdemo/image-20240418163011967.png) + +## 1.4 接口说明 + +### 1.4.1 uapi_pin_set_mode() + +| **定义:** | errcode_t uapi_pin_set_mode(pin_t pin, pin_mode_t mode); | +| ------------ | -------------------------------------------------------- | +| **功能:** | 设置引脚复用模式 | +| **参数:** | pin:io
mode:复用模式 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pinctrl.h | + +### 1.4.2 uapi_uart_init() + +| **定义:** | errcode_t uapi_uart_init(uart_bus_t bus, const uart_pin_config_t *pins, const uart_attr_t *attr, const uart_extra_attr_t *extra_attr, uart_buffer_config_t *uart_buffer_config); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 初始化指定的串口 | +| **参数:** | bus:串口号
pins:UART中使用的PIN,包括TX, RX, RTS和CTS
attr:UART的基础配置参数
extra_attr :UART的高级配置参数
uart_buffer_config:指定UART的接收Buffer | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\uart.h | + +### 1.4.3 uapi_uart_deinit() + +| **定义:** | errcode_t uapi_uart_deinit(uart_bus_t bus); | +| ------------ | ------------------------------------------- | +| **功能:** | 去初始化指定的串口 | +| **参数:** | bus:串口号 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\uart.h | + +### 1.4.4 uapi_uart_write() + +| **定义:** | int32_t uapi_uart_write(uart_bus_t bus, const uint8_t *buffer, uint32_t length, uint32_t timeout); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 将数据发送到已经打开的UART上,使用直接发送的方式 | +| **参数:** | bus:串口号
buffer: 要发送的数据Buffer
length:要发送的数据Buffer长度
timeout:超时时间 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | iinclude\driver\uart.h | + +### 1.4.5 uapi_uart_write_int() + +| **定义:** | errcode_t uapi_uart_write_int(uart_bus_t bus, const uint8_t *buffer, uint32_t length,void *params, uart_tx_callback_t finished_with_buffer_func); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 使用中断模式将数据发送到已经打开的UART上,当数据发送完成,会调用回调函数 | +| **参数:** | bus:串口号
buffer: 要发送的数据Buffer
length:要发送的数据Buffer长度
params:传递到完成传输的回调函数的参数
finished_with_buffer_func:数据发送完成的回调函数 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\uart.h | + +### 1.4.6 uapi_uart_read() + +| **定义:** | int32_t uapi_uart_read(uart_bus_t bus, const uint8_t *buffer, uint32_t length, uint32_t timeout); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 从UART读取数据 | +| **参数:** | bus:串口号
buffer: 存储接收数据的Buffer
length:存储接收数据Buffer长度
timeout:超时时间 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\uart.h | + +### 1.4.7 uapi_uart_register_rx_callback() + +| **定义:** | errcode_t uapi_uart_register_rx_callback(uart_bus_t bus, uart_rx_condition_t condition, uint32_t size, uart_rx_callback_t callback); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 注册接收回调函数,这个回调函数会根据触发条件和Size触发。 | +| **参数:** | bus:串口号
condition:回调触发的条件
size:如果触发条件涉及到数据长度,这个参数就表示需要的数据长度
callback:接收数据的回调函数 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\uart.h | + +## 1.5 具体实现 + + 步骤一:设置GPIO复用uart功能。 + + 步骤二:配置uart参数,例如波特率、数据位、停止位、校验位等。 + + 步骤三:初始化uart设备。 + + 步骤四:通过uapi_uart_write函数写数据。 + + 步骤五:通过uapi_uart_read函数读数据。 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”uartdemo“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\uartdemo文件里面内容拷贝到**步骤一创建的Sample文件夹中”uartdemo“**。 + + ![image-20240418162506313](../../../docs/pic/uartdemo/image-20240418162506313.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support UARTDEMO Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240418162620764 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七:软件烧录成功后,按一下开发板的RESET按键复位开发板,烧录完成后,每隔5S串口循环打印“hello uart1”。 + + + ![image-20240418163011967](../../../docs/pic/uartdemo/image-20240418163011967.png) \ No newline at end of file diff --git a/src/vendor/test/uartdemo/uart_demo.c b/src/vendor/test/uartdemo/uart_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..61345e6c895f4419b969e46597d89162e20fff79 --- /dev/null +++ b/src/vendor/test/uartdemo/uart_demo.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "pinctrl.h" +#include "uart.h" +#include "watchdog.h" +#include "osal_debug.h" +#include "soc_osal.h" +#include "app_init.h" + +#define UART_BAUDRATE 115200 +#define UART_DATA_BITS 3 +#define UART_STOP_BITS 1 +#define UART_PARITY_BIT 0 +#define UART_TRANSFER_SIZE 18 +#define CONFIG_UART1_TXD_PIN 15 +#define CONFIG_UART1_RXD_PIN 16 +#define CONFIG_UART1_PIN_MODE 1 +#define CONFIG_UART1_BUS_ID 1 +#define CONFIG_UART_INT_WAIT_MS 5 + +#define UART_TASK_STACK_SIZE 0x1000 +#define UART_TASK_DURATION_MS 1000 +#define UART_TASK_PRIO 17 + +static uint8_t g_app_uart_tx_buff[UART_TRANSFER_SIZE] = "hello uart1"; +static uint8_t g_app_uart_rx_buff[UART_TRANSFER_SIZE] = {0}; + +#define CONFIG_UART_POLL_TRANSFER_MODE 1 +#if defined(CONFIG_UART_POLL_TRANSFER_MODE) +// 轮询读取uart值 +#endif + +#if defined(CONFIG_UART_INT_TRANSFER_MODE) +static uint8_t g_app_uart_int_rx_flag = 0; +#endif + +static uart_buffer_config_t g_app_uart_buffer_config = {.rx_buffer = g_app_uart_rx_buff, + .rx_buffer_size = UART_TRANSFER_SIZE}; + +static void app_uart_init_pin(void) +{ + uapi_pin_set_mode(CONFIG_UART1_TXD_PIN, CONFIG_UART1_PIN_MODE); + uapi_pin_set_mode(CONFIG_UART1_RXD_PIN, CONFIG_UART1_PIN_MODE); +} + +static void app_uart_init_config(void) +{ + uart_attr_t attr = {.baud_rate = UART_BAUDRATE, + .data_bits = UART_DATA_BITS, + .stop_bits = UART_STOP_BITS, + .parity = UART_PARITY_BIT}; + + uart_pin_config_t pin_config = {.tx_pin = S_MGPIO0, .rx_pin = S_MGPIO1, .cts_pin = PIN_NONE, .rts_pin = PIN_NONE}; + uapi_uart_deinit(CONFIG_UART1_BUS_ID); // 重点,UART初始化之前需要去初始化,否则会报0x80001044 + int res = uapi_uart_init(CONFIG_UART1_BUS_ID, &pin_config, &attr, NULL, &g_app_uart_buffer_config); + if (res != 0) { + printf("uart init failed res = %02x\r\n", res); + } +} + +#if defined(CONFIG_UART_INT_TRANSFER_MODE) +static void app_uart_read_int_handler(const void *buffer, uint16_t length, bool error) +{ + unused(error); + if (buffer == NULL || length == 0) { + osal_printk("uart%d int mode transfer illegal data!\r\n", CONFIG_UART1_BUS_ID); + return; + } + + uint8_t *buff = (uint8_t *)buffer; + if (memcpy_s(g_app_uart_rx_buff, length, buff, length) != EOK) { + osal_printk("uart%d int mode data copy fail!\r\n", CONFIG_UART1_BUS_ID); + return; + } + osal_printk("uart write data = %s\r\n", buff); + g_app_uart_int_rx_flag = 1; +} + +static void app_uart_write_int_handler(const void *buffer, uint32_t length, const void *params) +{ + unused(params); + uint8_t *buff = (void *)buffer; + for (uint8_t i = 0; i < length; i++) { + osal_printk("uart%d write data[%d] = %d\r\n", CONFIG_UART1_BUS_ID, i, buff[i]); + } +} +#endif + +void *uart_task(const char *arg) +{ + unused(arg); + /* UART pinmux. */ + app_uart_init_pin(); + /* UART init config. */ + app_uart_init_config(); + +#if defined(CONFIG_UART_INT_TRANSFER_MODE) + osal_printk("uart%d int mode register receive callback start!\r\n", CONFIG_UART1_BUS_ID); + if (uapi_uart_register_rx_callback(CONFIG_UART1_BUS_ID, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE, 1, + app_uart_read_int_handler) == ERRCODE_SUCC) { + osal_printk("uart%d int mode register receive callback succ!\r\n", CONFIG_UART1_BUS_ID); + } +#endif + while (1) { + osal_mdelay(UART_TASK_DURATION_MS); +#if defined(CONFIG_UART_POLL_TRANSFER_MODE) + osal_printk("uart%d poll mode send start!, len = %d\r\n", CONFIG_UART1_BUS_ID, sizeof(g_app_uart_rx_buff)); + (void)uapi_watchdog_kick(); + if (uapi_uart_write(CONFIG_UART1_BUS_ID, g_app_uart_tx_buff, UART_TRANSFER_SIZE, 0) == UART_TRANSFER_SIZE) { + osal_printk("uart%d poll mode send back succ!\r\n", CONFIG_UART1_BUS_ID); + } + if (uapi_uart_read(CONFIG_UART1_BUS_ID, g_app_uart_rx_buff, UART_TRANSFER_SIZE, 0) > 0) { + osal_printk("uart%d poll mode receive succ!, g_app_uart_rx_buff = %s\r\n", CONFIG_UART1_BUS_ID, + g_app_uart_rx_buff); + } +#endif +#if defined(CONFIG_UART_INT_TRANSFER_MODE) + while (g_app_uart_int_rx_flag != 1) { + osDelay(CONFIG_UART_INT_WAIT_MS); + } + g_app_uart_int_rx_flag = 0; + osal_printk("uart%d int mode send back!\r\n", CONFIG_UART1_BUS_ID); + if (uapi_uart_write_int(CONFIG_UART1_BUS_ID, g_app_uart_tx_buff, UART_TRANSFER_SIZE, 0, + app_uart_write_int_handler) == ERRCODE_SUCC) { + osal_printk("uart%d int mode send back succ!\r\n", CONFIG_UART1_BUS_ID); + } +#endif + } + return NULL; +} + +static void uart_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)uart_task, 0, "UartTask", UART_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, UART_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the uart_entry. */ +app_run(uart_entry); \ No newline at end of file diff --git a/src/vendor/test/uartdemo/uart_demo.h b/src/vendor/test/uartdemo/uart_demo.h new file mode 100644 index 0000000000000000000000000000000000000000..b947026623a8cd595f6058b4b46642b0a0279236 --- /dev/null +++ b/src/vendor/test/uartdemo/uart_demo.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 UART_DEMO_H +#define UART_DEMO_H + +void *uart_task(const char *arg); + +#endif // AHT20_H \ No newline at end of file diff --git a/src/vendor/test/ultrasonic/CMakeLists.txt b/src/vendor/test/ultrasonic/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..dc54506d1d57ee0a1a243368a2bfefb2ae3e43a3 --- /dev/null +++ b/src/vendor/test/ultrasonic/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/hcsr04.c" "${CMAKE_CURRENT_SOURCE_DIR}/ssd1306_fonts.c" "${CMAKE_CURRENT_SOURCE_DIR}/ssd1306.c" PARENT_SCOPE) diff --git a/src/vendor/test/ultrasonic/README.md b/src/vendor/test/ultrasonic/README.md new file mode 100644 index 0000000000000000000000000000000000000000..de12bdbf137e899e21fb920d8ed88a6a3a693aab --- /dev/null +++ b/src/vendor/test/ultrasonic/README.md @@ -0,0 +1,109 @@ +# hcsr04 + +## 1.1 介绍 + +**功能介绍:** 本实验实现了通过GPIO 00和 GPIO 01实现超声波测距,并在屏幕上显示距离。 + +**软件概述:** GPIO引脚输出高低电平状态。 + +**硬件概述:** 核心板、交通灯板、HCSR04超声波。超声波数据手册参考https://gitee.com/HiSpark/hi3861_hdu_iot_application/issues/I6WPSS?from=project-issue 里面的HCSR04超声波模块。 超声波(TRIG)插在底板SDA位置,在底板左端寻找SDA,并通过核心板丝印可以看出SDA对应核心板GPIO 00;以超声波ECHO为参考:超声波(ECHO)插在底板SCK位置,在底板左端寻找SCK,并通过核心板丝印可以看出SCK对应核心板GPIO 01硬件搭建要求如图所示: + + 参考[核心板原理图](../../../docs/hardware/HIHOPE_NEARLINK_DK_3863E_V03.pdf)、[底板原理图](../../../docs/hardware/HiSpark_WiFi_IoT_EXB_VER.A.pdf) + + image-20240227154223440 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 本实验实现了通过GPIO 00和 GPIO 01实现超声波测距,并在屏幕上显示距离。 + + image-20240227154223440image-20240227154244814 + +## 1.4 接口介绍 + +### 1.4.1 uapi_gpio_set_dir() + +| **定义:** | errcode_t uapi_gpio_set_dir(pin_t pin, gpio_direction_t dir); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置GPIO的输入输出方向函数 | +| **参数:** | pin: io引脚
dir:输入输出方向 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +### 1.4.2 uapi_gpio_set_val() + +| 定义: | errcode_t uapi_gpio_set_val(pin_t pin, gpio_level_t level); | +| ------------ | ----------------------------------------------------------- | +| **功能:** | 设置GPIO的输出状态 | +| **参数:** | pin:io引脚
level:设置输出为高或低 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\gpio.h | + +### 1.4.3 uapi_pin_set_mode() + +| **定义:** | errcode_t uapi_pin_set_mode(pin_t pin, pin_mode_t mode); | +| ------------ | -------------------------------------------------------- | +| **功能:** | 设置引脚复用模式 | +| **参数:** | pin:io
mode:复用模式 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\driver\pinctrl.h | + +### 1.4.4 uapi_gpio_get_val() + +| **定义:** | gpio_level_t uapi_gpio_get_val(pin_t pin); | +| ------------ | ------------------------------------------ | +| **功能:** | 读取GPIO的输入状态 | +| **参数:** | pin:io | +| **返回值:** | GPIO输入电平值 | +| **依赖:** | include\driver\gpio.h | + +## 1.5 具体实现 + + 步骤一:设置GPIO为输出模式。 + + 步骤二:设置GPIO输出为高或低。 + + 步骤三:通过输出GPIO高低电平状态并模拟对应PWM波形。 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples\peripheral文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”servo“。 + + ![image-20240205104416249](../../../docs/pic/timer/image-20240205104416249-17119401758005.png) + +- 步骤二:将open_cfbb\vendor\hispark\servo文件里面内容拷贝到**步骤一创建的Sample文件夹中”servo“**。 + + ![image-20240418154408339](../../../docs/pic/ultrasonic/image-20240418154408339.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support LED Sample”,点击Save,关闭弹窗。 + + image-20240205104929713image-20240205105234692image-20240418154439988 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七“软件烧录成功后,按一下开发板的RESET按键复位开发板,在屏幕上显示对应距离。 + + image-20240227154223440image-20240227154244814 \ No newline at end of file diff --git a/src/vendor/test/ultrasonic/hcsr04.c b/src/vendor/test/ultrasonic/hcsr04.c new file mode 100644 index 0000000000000000000000000000000000000000..983836038ac59ad6a82ee26083f4768521a1373c --- /dev/null +++ b/src/vendor/test/ultrasonic/hcsr04.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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. + */ + +/* + HCSR04 超声波模块的相关API接口 +*/ + +#include "pinctrl.h" +#include "common_def.h" +#include "soc_osal.h" +#include "gpio.h" +#include "systick.h" +#include "i2c.h" +#include "osal_debug.h" +#include "ssd1306_fonts.h" +#include "ssd1306.h" +#include "watchdog.h" +#include "app_init.h" + +#define DELAY_US20 20 +#define DELAY_10MS 10 +#define BSP_LED_0 0 +#define BSP_LED_1 1 +#define CONFIG_I2C_SCL_MASTER_PIN 15 +#define CONFIG_I2C_SDA_MASTER_PIN 16 +#define CONFIG_I2C_MASTER_PIN_MODE 2 +#define I2C_MASTER_ADDR 0x0 +#define I2C_SLAVE1_ADDR 0x38 +#define I2C_SET_BANDRATE 400000 +#define HCSR04_TASK_STACK_SIZE 0x1000 +#define HCSR04_TASK_PRIO 17 + +void app_i2c_init_pin(void) +{ + uapi_pin_set_mode(CONFIG_I2C_SCL_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_I2C_SDA_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE); +} + +void Hcsr04Init(void) +{ + + uapi_pin_set_mode(BSP_LED_0, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(BSP_LED_0, GPIO_DIRECTION_OUTPUT); + uapi_gpio_set_val(BSP_LED_0, GPIO_LEVEL_LOW); + uapi_pin_set_mode(BSP_LED_1, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(BSP_LED_1, GPIO_DIRECTION_INPUT); +} + +float GetDistance(void) +{ + static uint64_t start_time = 0, time = 0; + float distance = 0.0; + gpio_level_t value = 0; + unsigned int flag = 0; + static char line[32] = {0}; + /* + * 设置GPIO7输出低电平 + * 给trig发送至少10us-20us的高电平脉冲,以触发传感器测距 + * Set GPIO7 to output direction + * Send a high level pulse of at least 10us to the trig to trigger the range measurement of the sensor + */ + uapi_gpio_set_val(BSP_LED_0, GPIO_LEVEL_HIGH); + uapi_systick_delay_us(DELAY_US20); + uapi_gpio_set_val(BSP_LED_0, GPIO_LEVEL_LOW); + /* + * 计算与障碍物之间的距离 + * Calculate the distance from the obstacle + */ + while (1) { + /* + * 获取GPIO8的输入电平状态 + * Get the input level status of GPIO8 + */ + value = uapi_gpio_get_output_val(BSP_LED_1); + /* + * 判断GPIO8的输入电平是否为高电平并且flag为0 + * Judge whether the input level of GPIO8 is high and the flag is 0 + */ + if (value == GPIO_LEVEL_HIGH && flag == 0) { + /* + * 获取系统时间 + * get SysTime + */ + start_time = uapi_systick_get_us(); + flag = 1; + } + /* + * 判断GPIO8的输入电平是否为低电平并且flag为1 + * Judge whether the input level of GPIO8 is low and the flag is 1 + */ + if (value == GPIO_LEVEL_LOW && flag == 1) { + /* + * 获取高电平持续时间 + * Get high level duration + */ + time = uapi_systick_get_us() - start_time; + break; + } + } + /* 计算距离障碍物距离(340米/秒 转换为 0.034厘米/微秒, 2代表去来,两倍距离) */ + /* Calculate the distance from the obstacle */ + /* (340 m/s is converted to 0.034 cm/microsecond 2 represents going and coming, twice the distance) */ + distance = time * 0.034 / 2; + sprintf(line, "distance: %.2f", distance); + ssd1306_SetCursor(0, 0); + ssd1306_DrawString(line, Font_7x10, White); + ssd1306_UpdateScreen(); + return distance; +} + +void Hcsr04SampleTask(void) +{ + Hcsr04Init(); + printf("Hcsr04SampleTask init\r\n"); + uint32_t baudrate = I2C_SET_BANDRATE; + uint32_t hscode = I2C_MASTER_ADDR; + app_i2c_init_pin(); + errcode_t ret = uapi_i2c_master_init(1, baudrate, hscode); + if (ret != 0) { + printf("i2c init failed, ret = %0x\r\n", ret); + } + ssd1306_Init(); + ssd1306_Fill(Black); + while (1) { + GetDistance(); + osal_mdelay(DELAY_10MS); + } +} + +void Hcsr04SampleEntry(void) +{ + uint32_t ret; + osal_task *taskid; + // 创建任务调度 + osal_kthread_lock(); + // 创建任务1 + taskid = osal_kthread_create((osal_kthread_handler)Hcsr04SampleTask, NULL, "Hcsr04Task", HCSR04_TASK_STACK_SIZE); + ret = osal_kthread_set_priority(taskid, HCSR04_TASK_PRIO); + if (ret != OSAL_SUCCESS) { + printf("create task1 failed .\n"); + } + osal_kthread_unlock(); +} +app_run(Hcsr04SampleEntry); \ No newline at end of file diff --git a/src/vendor/test/ultrasonic/ssd1306.c b/src/vendor/test/ultrasonic/ssd1306.c new file mode 100644 index 0000000000000000000000000000000000000000..e7c4dab13006eb2a6cfd7513fa37f76b2489776e --- /dev/null +++ b/src/vendor/test/ultrasonic/ssd1306.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 +#include +#include +#include +#include +#include +#include +#include "i2c.h" +#include "soc_osal.h" +#include "ssd1306.h" + +#define CONFIG_I2C_MASTER_BUS_ID 1 +#define I2C_SLAVE2_ADDR 0x3C +#define SSD1306_CTRL_CMD 0x00 +#define SSD1306_CTRL_DATA 0x40 +#define SSD1306_MASK_CONT (0x1 << 7) +#define DOUBLE 2 + +void ssd1306_Reset(void) +{ + // Wait for the screen to boot,1ms The delay here is very important + osal_mdelay(1); +} + +static uint32_t ssd1306_SendData(uint8_t *buffer, uint32_t size) +{ + uint16_t dev_addr = I2C_SLAVE2_ADDR; + i2c_data_t data = {0}; + data.send_buf = buffer; + data.send_len = size; + uint32_t retval = uapi_i2c_master_write(CONFIG_I2C_MASTER_BUS_ID, dev_addr, &data); + if (retval != 0) { + printf("I2cWrite(%02X) failed, %0X!\n", data.send_buf[1], retval); + return retval; + } + return 0; +} + +static uint32_t ssd1306_WiteByte(uint8_t regAddr, uint8_t byte) +{ + uint8_t buffer[] = {regAddr, byte}; + return ssd1306_SendData(buffer, sizeof(buffer)); +} + +// Send a byte to the command register +void ssd1306_WriteCommand(uint8_t byte) +{ + ssd1306_WiteByte(SSD1306_CTRL_CMD, byte); +} + +// Send data +void ssd1306_WriteData(uint8_t *buffer, uint32_t buff_size) +{ + uint8_t data[SSD1306_WIDTH * DOUBLE] = {0}; + for (uint32_t i = 0; i < buff_size; i++) { + data[i * DOUBLE] = SSD1306_CTRL_DATA | SSD1306_MASK_CONT; + data[i * DOUBLE + 1] = buffer[i]; + } + data[(buff_size - 1) * DOUBLE] = SSD1306_CTRL_DATA; + ssd1306_SendData(data, sizeof(data)); +} + +// Screenbuffer +static uint8_t SSD1306_Buffer[SSD1306_BUFFER_SIZE]; + +// Screen object +static SSD1306_t SSD1306; + +/* Fills the Screenbuffer with values from a given buffer of a fixed length */ +SSD1306_Error_t ssd1306_FillBuffer(uint8_t *buf, uint32_t len) +{ + SSD1306_Error_t ret = SSD1306_ERR; + if (len <= SSD1306_BUFFER_SIZE) { + memcpy_s(SSD1306_Buffer, len + 1, buf, len); + ret = SSD1306_OK; + } + return ret; +} + +void ssd1306_Init_CMD(void) +{ + ssd1306_WriteCommand(0xA4); // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content + + ssd1306_WriteCommand(0xD3); // -set display offset - CHECK + ssd1306_WriteCommand(0x00); // -not offset + + ssd1306_WriteCommand(0xD5); // --set display clock divide ratio/oscillator frequency + ssd1306_WriteCommand(0xF0); // --set divide ratio + + ssd1306_WriteCommand(0xD9); // --set pre-charge period + ssd1306_WriteCommand(0x11); // 0x22 by default + + ssd1306_WriteCommand(0xDA); // --set com pins hardware configuration - CHECK +#if (SSD1306_HEIGHT == 32) + ssd1306_WriteCommand(0x02); +#elif (SSD1306_HEIGHT == 64) + ssd1306_WriteCommand(0x12); +#elif (SSD1306_HEIGHT == 128) + ssd1306_WriteCommand(0x12); +#else +#error "Only 32, 64, or 128 lines of height are supported!" +#endif + + ssd1306_WriteCommand(0xDB); // --set vcomh + ssd1306_WriteCommand(0x30); // 0x20,0.77xVcc, 0x30,0.83xVcc + + ssd1306_WriteCommand(0x8D); // --set DC-DC enable + ssd1306_WriteCommand(0x14); // + ssd1306_SetDisplayOn(1); // --turn on SSD1306 panel +} + +// Initialize the oled screen +void ssd1306_Init(void) +{ + // Reset OLED + ssd1306_Reset(); + // Init OLED + ssd1306_SetDisplayOn(0); // display off + + ssd1306_WriteCommand(0x20); // Set Memory Addressing Mode + ssd1306_WriteCommand(0x00); // 00b,Horizontal Addressing Mode; 01b,Vertical Addressing Mode; + // 10b,Page Addressing Mode (RESET); 11b,Invalid + + ssd1306_WriteCommand(0xB0); // Set Page Start Address for Page Addressing Mode,0-7 + +#ifdef SSD1306_MIRROR_VERT + ssd1306_WriteCommand(0xC0); // Mirror vertically +#else + ssd1306_WriteCommand(0xC8); // Set COM Output Scan Direction +#endif + + ssd1306_WriteCommand(0x00); // ---set low column address + ssd1306_WriteCommand(0x10); // ---set high column address + + ssd1306_WriteCommand(0x40); // --set start line address - CHECK + + ssd1306_SetContrast(0xFF); + +#ifdef SSD1306_MIRROR_HORIZ + ssd1306_WriteCommand(0xA0); // Mirror horizontally +#else + ssd1306_WriteCommand(0xA1); // --set segment re-map 0 to 127 - CHECK +#endif + +#ifdef SSD1306_INVERSE_COLOR + ssd1306_WriteCommand(0xA7); // --set inverse color +#else + ssd1306_WriteCommand(0xA6); // --set normal color +#endif + +// Set multiplex ratio. +#if (SSD1306_HEIGHT == 128) + // Found in the Luma Python lib for SH1106. + ssd1306_WriteCommand(0xFF); +#else + ssd1306_WriteCommand(0xA8); // --set multiplex ratio(1 to 64) - CHECK +#endif + +#if (SSD1306_HEIGHT == 32) + ssd1306_WriteCommand(0x1F); // +#elif (SSD1306_HEIGHT == 64) + ssd1306_WriteCommand(0x3F); // +#elif (SSD1306_HEIGHT == 128) + ssd1306_WriteCommand(0x3F); // Seems to work for 128px high displays too. +#else +#error "Only 32, 64, or 128 lines of height are supported!" +#endif + ssd1306_Init_CMD(); + // Clear screen + ssd1306_Fill(Black); + + // Flush buffer to screen + ssd1306_UpdateScreen(); + + // Set default values for screen object + SSD1306.CurrentX = 0; + SSD1306.CurrentY = 0; + + SSD1306.Initialized = 1; +} + +// Fill the whole screen with the given color +void ssd1306_Fill(SSD1306_COLOR color) +{ + /* Set memory */ + uint32_t i; + + for (i = 0; i < sizeof(SSD1306_Buffer); i++) { + SSD1306_Buffer[i] = (color == Black) ? 0x00 : 0xFF; + } +} + +// Write the screenbuffer with changed to the screen +void ssd1306_UpdateScreen(void) +{ + // Write data to each page of RAM. Number of pages + // depends on the screen height: + // + // * 32px == 4 pages + // * 64px == 8 pages + // * 128px == 16 pages + + uint8_t cmd[] = { + 0X21, // 设置列起始和结束地址 + 0X00, // 列起始地址 0 + 0X7F, // 列终止地址 127 + 0X22, // 设置页起始和结束地址 + 0X00, // 页起始地址 0 + 0X07, // 页终止地址 7 + }; + uint32_t count = 0; + uint8_t data[sizeof(cmd) * DOUBLE + SSD1306_BUFFER_SIZE + 1] = {}; + + // copy cmd + for (uint32_t i = 0; i < sizeof(cmd) / sizeof(cmd[0]); i++) { + data[count++] = SSD1306_CTRL_CMD | SSD1306_MASK_CONT; + data[count++] = cmd[i]; + } + + // copy frame data + data[count++] = SSD1306_CTRL_DATA; + memcpy_s(&data[count], SSD1306_BUFFER_SIZE + 1, SSD1306_Buffer, SSD1306_BUFFER_SIZE); + count += sizeof(SSD1306_Buffer); + + // send to i2c bus + uint32_t retval = ssd1306_SendData(data, count); + if (retval != 0) { + printf("ssd1306_UpdateScreen send frame data filed: %d!\r\n", retval); + } +} + +// Draw one pixel in the screenbuffer +// X => X Coordinate +// Y => Y Coordinate +// color => Pixel color +void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color) +{ + if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) { + // Don't write outside the buffer + return; + } + SSD1306_COLOR color1 = color; + // Check if pixel should be inverted + if (SSD1306.Inverted) { + color1 = (SSD1306_COLOR)!color1; + } + + // Draw in the right color + uint32_t c = 8; // 8 + if (color == White) { + SSD1306_Buffer[x + (y / c) * SSD1306_WIDTH] |= 1 << (y % c); + } else { + SSD1306_Buffer[x + (y / c) * SSD1306_WIDTH] &= ~(1 << (y % c)); + } +} + +// Draw 1 char to the screen buffer +// ch => char om weg te schrijven +// Font => Font waarmee we gaan schrijven +// color => Black or White +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color) +{ + uint32_t i, b, j; + + // Check if character is valid + uint32_t ch_min = 32; // 32 + uint32_t ch_max = 126; // 126 + if ((uint32_t)ch < ch_min || (uint32_t)ch > ch_max) { + return 0; + } + + // Check remaining space on current line + if (SSD1306_WIDTH < (SSD1306.CurrentX + Font.FontWidth) || SSD1306_HEIGHT < (SSD1306.CurrentY + Font.FontHeight)) { + // Not enough space on current line + return 0; + } + + // Use the font to write + for (i = 0; i < Font.FontHeight; i++) { + b = Font.data[(ch - ch_min) * Font.FontHeight + i]; + for (j = 0; j < Font.FontWidth; j++) { + if ((b << j) & 0x8000) { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)color); + } else { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color); + } + } + } + + // The current space is now taken + SSD1306.CurrentX += Font.FontWidth; + + // Return written char for validation + return ch; +} + +// Write full string to screenbuffer +char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color) +{ + // Write until null-byte + char *str1 = str; + while (*str1) { + if (ssd1306_DrawChar(*str1, Font, color) != *str1) { + // Char could not be written + return *str1; + } + // Next char + str1++; + } + + // Everything ok + return *str1; +} + +// Position the cursor +void ssd1306_SetCursor(uint8_t x, uint8_t y) +{ + SSD1306.CurrentX = x; + SSD1306.CurrentY = y; +} + +// Draw line by Bresenhem's algorithm +void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) +{ + uint8_t x = x1; + uint8_t y = y1; + int32_t deltaX = abs(x2 - x1); + int32_t deltaY = abs(y2 - y1); + int32_t signX = ((x1 < x2) ? 1 : -1); + int32_t signY = ((y1 < y2) ? 1 : -1); + int32_t error = deltaX - deltaY; + int32_t error2; + ssd1306_DrawPixel(x2, y2, color); + while ((x1 != x2) || (y1 != y2)) { + ssd1306_DrawPixel(x1, y1, color); + error2 = error * DOUBLE; + if (error2 > -deltaY) { + error -= deltaY; + x += signX; + } else { + /* nothing to do */ + } + if (error2 < deltaX) { + error += deltaX; + y += signY; + } else { + /* nothing to do */ + } + } +} + +// Draw polyline +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color) +{ + uint16_t i; + if (par_vertex != 0) { + for (i = 1; i < par_size; i++) { + ssd1306_DrawLine(par_vertex[i - 1].x, par_vertex[i - 1].y, par_vertex[i].x, par_vertex[i].y, color); + } + } else { + /* nothing to do */ + } + return; +} + +// Draw circle by Bresenhem's algorithm +void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color) +{ + int32_t x = -par_r; + int32_t y = 0; + int32_t b = 2; + int32_t err = b - b * par_r; + int32_t e2; + + if (par_x >= SSD1306_WIDTH || par_y >= SSD1306_HEIGHT) { + return; + } + + do { + ssd1306_DrawPixel(par_x - x, par_y + y, par_color); + ssd1306_DrawPixel(par_x + x, par_y + y, par_color); + ssd1306_DrawPixel(par_x + x, par_y - y, par_color); + ssd1306_DrawPixel(par_x - x, par_y - y, par_color); + e2 = err; + if (e2 <= y) { + y++; + err = err + (y * b + 1); + if (-x == y && e2 <= x) { + e2 = 0; + } else { + /* nothing to do */ + } + } else { + /* nothing to do */ + } + if (e2 > x) { + x++; + err = err + (x * b + 1); + } else { + /* nothing to do */ + } + } while (x <= 0); + + return; +} + +// Draw rectangle +void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) +{ + ssd1306_DrawLine(x1, y1, x2, y1, color); + ssd1306_DrawLine(x2, y1, x2, y2, color); + ssd1306_DrawLine(x2, y2, x1, y2, color); + ssd1306_DrawLine(x1, y2, x1, y1, color); +} + +void ssd1306_DrawBitmap(const uint8_t *bitmap, uint32_t size) +{ + unsigned int c = 8; + uint8_t rows = size * c / SSD1306_WIDTH; + if (rows > SSD1306_HEIGHT) { + rows = SSD1306_HEIGHT; + } + for (uint8_t y = 0; y < rows; y++) { + for (uint8_t x = 0; x < SSD1306_WIDTH; x++) { + uint8_t byte = bitmap[(y * SSD1306_WIDTH / c) + (x / c)]; + uint8_t bit = byte & (0x80 >> (x % c)); + ssd1306_DrawPixel(x, y, bit ? White : Black); + } + } +} + +void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data, uint32_t size) +{ + uint32_t stride = w; + uint8_t h = w; // 字体宽高一样 + uint8_t width = w; + if (x + w > SSD1306_WIDTH || y + h > SSD1306_HEIGHT || w * h == 0) { + printf("%dx%d @ %d,%d out of range or invalid!\r\n", w, h, x, y); + return; + } + + width = (width <= SSD1306_WIDTH ? width : SSD1306_WIDTH); + h = (h <= SSD1306_HEIGHT ? h : SSD1306_HEIGHT); + stride = (stride == 0 ? w : stride); + unsigned int c = 8; + + uint8_t rows = size * c / stride; + for (uint8_t i = 0; i < rows; i++) { + uint32_t base = i * stride / c; + for (uint8_t j = 0; j < width; j++) { + uint32_t idx = base + (j / c); + uint8_t byte = idx < size ? data[idx] : 0; + uint8_t bit = byte & (0x80 >> (j % c)); + ssd1306_DrawPixel(x + j, y + i, bit ? White : Black); + } + } +} + +void ssd1306_SetContrast(const uint8_t value) +{ + const uint8_t kSetContrastControlRegister = 0x81; + ssd1306_WriteCommand(kSetContrastControlRegister); + ssd1306_WriteCommand(value); +} + +void ssd1306_SetDisplayOn(const uint8_t on) +{ + uint8_t value; + if (on) { + value = 0xAF; // Display on + SSD1306.DisplayOn = 1; + } else { + value = 0xAE; // Display off + SSD1306.DisplayOn = 0; + } + ssd1306_WriteCommand(value); +} + +uint8_t ssd1306_GetDisplayOn(void) +{ + return SSD1306.DisplayOn; +} + +int g_ssd1306_current_loc_v = 0; +#define SSD1306_INTERVAL_V (15) + +void ssd1306_ClearOLED(void) +{ + ssd1306_Fill(Black); + g_ssd1306_current_loc_v = 0; +} + +void ssd1306_printf(char *fmt, ...) +{ + char buffer[20]; + int ret = 0; + if (fmt) { + va_list argList; + va_start(argList, fmt); + ret = vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), fmt, argList); + if (ret < 0) { + printf("buffer is null\r\n"); + } + va_end(argList); + ssd1306_SetCursor(0, g_ssd1306_current_loc_v); + ssd1306_DrawString(buffer, Font_7x10, White); + + ssd1306_UpdateScreen(); + } + g_ssd1306_current_loc_v += SSD1306_INTERVAL_V; +} diff --git a/src/vendor/test/ultrasonic/ssd1306.h b/src/vendor/test/ultrasonic/ssd1306.h new file mode 100644 index 0000000000000000000000000000000000000000..769f19c7af3a3aaf0f6fd007d62721c007b0e7d1 --- /dev/null +++ b/src/vendor/test/ultrasonic/ssd1306.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 SSD1306_H +#define SSD1306_H + +#include +#include +#include "ssd1306_fonts.h" + +// SSD1306 OLED height in pixels +#ifndef SSD1306_HEIGHT +#define SSD1306_HEIGHT 64 +#endif + +// SSD1306 width in pixels +#ifndef SSD1306_WIDTH +#define SSD1306_WIDTH 128 +#endif + +// some LEDs don't display anything in first two columns + +#ifndef SSD1306_BUFFER_SIZE +#define SSD1306_BUFFER_SIZE (SSD1306_WIDTH * SSD1306_HEIGHT / 8) +#endif + +// Enumeration for screen colors +typedef enum { + Black = 0x00, // Black color, no pixel + White = 0x01 // Pixel is set. Color depends on OLED +} SSD1306_COLOR; + +typedef enum { + SSD1306_OK = 0x00, + SSD1306_ERR = 0x01 // Generic error. +} SSD1306_Error_t; + +// Struct to store transformations +typedef struct { + uint16_t CurrentX; + uint16_t CurrentY; + uint8_t Inverted; + uint8_t Initialized; + uint8_t DisplayOn; +} SSD1306_t; +typedef struct { + uint8_t x; + uint8_t y; +} SSD1306_VERTEX; + +// Procedure definitions +void ssd1306_Init(void); +void ssd1306_Fill(SSD1306_COLOR color); +void ssd1306_SetCursor(uint8_t x, uint8_t y); +void ssd1306_UpdateScreen(void); + +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color); +char ssd1306_DrawString(char *str, FontDef Font, SSD1306_COLOR color); + +void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color); +void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color); +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color); +void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color); +void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color); +void ssd1306_DrawBitmap(const uint8_t *bitmap, uint32_t size); +void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, const uint8_t *data, uint32_t size); + +/** + * @brief Sets the contrast of the display. + * @param[in] value contrast to set. + * @note Contrast increases as the value increases. + * @note RESET = 7Fh. + */ +void ssd1306_SetContrast(const uint8_t value); +/** + * @brief Set Display ON/OFF. + * @param[in] on 0 for OFF, any for ON. + */ +void ssd1306_SetDisplayOn(const uint8_t on); +/** + * @brief Reads DisplayOn state. + * @return 0: OFF. + * 1: ON. + */ +uint8_t ssd1306_GetDisplayOn(void); + +// Low-level procedures +void ssd1306_Reset(void); +void ssd1306_WriteCommand(uint8_t byte); +void ssd1306_WriteData(uint8_t *buffer, size_t buff_size); +SSD1306_Error_t ssd1306_FillBuffer(uint8_t *buf, uint32_t len); +void ssd1306_ClearOLED(void); +void ssd1306_printf(char *fmt, ...); + +#endif // __SSD1306_H__ \ No newline at end of file diff --git a/src/vendor/test/ultrasonic/ssd1306_fonts.c b/src/vendor/test/ultrasonic/ssd1306_fonts.c new file mode 100644 index 0000000000000000000000000000000000000000..8053265cdef8a0474cc3506121ce65c54cc06d6f --- /dev/null +++ b/src/vendor/test/ultrasonic/ssd1306_fonts.c @@ -0,0 +1,819 @@ +/* + MIT License + + Copyright (c) 2018-2019, Alexey Dynda + + 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. +*/ +/* + * ssd1306xled_font6x8 is by Neven Boyanov + * ssd1306xled_font8x16 is by Neven Boyanov + * + * @created: 2014-08-12 + * @author: Neven Boyanov + * + * Copyright (c) 2015 Neven Boyanov, Tinusaur Team. All Rights Reserved. + * Distributed as open source software under MIT License, see LICENSE.txt file. + * Please, as a favour, retain the link http://tinusaur.org to The Tinusaur Project. + * + * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled + * + */ + +#include "ssd1306_fonts.h" + +/************************************6*8的点阵************************************/ +const unsigned char g_f6X8[][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // sp + {0x00, 0x00, 0x00, 0x2f, 0x00, 0x00}, // ! + {0x00, 0x00, 0x07, 0x00, 0x07, 0x00}, // " + {0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14}, // # + {0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12}, // $ + {0x00, 0x62, 0x64, 0x08, 0x13, 0x23}, // % + {0x00, 0x36, 0x49, 0x55, 0x22, 0x50}, // & + {0x00, 0x00, 0x05, 0x03, 0x00, 0x00}, // ' + {0x00, 0x00, 0x1c, 0x22, 0x41, 0x00}, // ( + {0x00, 0x00, 0x41, 0x22, 0x1c, 0x00}, // ) + {0x00, 0x14, 0x08, 0x3E, 0x08, 0x14}, // * + {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // + + {0x00, 0x00, 0x00, 0xA0, 0x60, 0x00}, // , + {0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // - + {0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // . + {0x00, 0x20, 0x10, 0x08, 0x04, 0x02}, // / + {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0 + {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00}, // 1 + {0x00, 0x42, 0x61, 0x51, 0x49, 0x46}, // 2 + {0x00, 0x21, 0x41, 0x45, 0x4B, 0x31}, // 3 + {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10}, // 4 + {0x00, 0x27, 0x45, 0x45, 0x45, 0x39}, // 5 + {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6 + {0x00, 0x01, 0x71, 0x09, 0x05, 0x03}, // 7 + {0x00, 0x36, 0x49, 0x49, 0x49, 0x36}, // 8 + {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E}, // 9 + {0x00, 0x00, 0x36, 0x36, 0x00, 0x00}, // : + {0x00, 0x00, 0x56, 0x36, 0x00, 0x00}, // ;号 + {0x00, 0x08, 0x14, 0x22, 0x41, 0x00}, // < + {0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // = + {0x00, 0x00, 0x41, 0x22, 0x14, 0x08}, // > + {0x00, 0x02, 0x01, 0x51, 0x09, 0x06}, // ? + {0x00, 0x32, 0x49, 0x59, 0x51, 0x3E}, // @ + {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C}, // A + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36}, // B + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22}, // C + {0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C}, // D + {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41}, // E + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01}, // F + {0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A}, // G + {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F}, // H + {0x00, 0x00, 0x41, 0x7F, 0x41, 0x00}, // I + {0x00, 0x20, 0x40, 0x41, 0x3F, 0x01}, // J + {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41}, // K + {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40}, // L + {0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F}, // M + {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F}, // N + {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E}, // O + {0x00, 0x7F, 0x09, 0x09, 0x09, 0x06}, // P + {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q + {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46}, // R + {0x00, 0x46, 0x49, 0x49, 0x49, 0x31}, // S + {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01}, // T + {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F}, // U + {0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F}, // V + {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F}, // W + {0x00, 0x63, 0x14, 0x08, 0x14, 0x63}, // X + {0x00, 0x07, 0x08, 0x70, 0x08, 0x07}, // Y + {0x00, 0x61, 0x51, 0x49, 0x45, 0x43}, // Z + {0x00, 0x00, 0x7F, 0x41, 0x41, 0x00}, // [ + {0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55}, // 55 + {0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ] + {0x00, 0x04, 0x02, 0x01, 0x02, 0x04}, // ^ + {0x00, 0x40, 0x40, 0x40, 0x40, 0x40}, // _ + {0x00, 0x00, 0x01, 0x02, 0x04, 0x00}, // ' + {0x00, 0x20, 0x54, 0x54, 0x54, 0x78}, // a + {0x00, 0x7F, 0x48, 0x44, 0x44, 0x38}, // b + {0x00, 0x38, 0x44, 0x44, 0x44, 0x20}, // c + {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F}, // d + {0x00, 0x38, 0x54, 0x54, 0x54, 0x18}, // e + {0x00, 0x08, 0x7E, 0x09, 0x01, 0x02}, // f + {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C}, // g + {0x00, 0x7F, 0x08, 0x04, 0x04, 0x78}, // h + {0x00, 0x00, 0x44, 0x7D, 0x40, 0x00}, // i + {0x00, 0x40, 0x80, 0x84, 0x7D, 0x00}, // j + {0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // k + {0x00, 0x00, 0x41, 0x7F, 0x40, 0x00}, // l + {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78}, // m + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x78}, // n + {0x00, 0x38, 0x44, 0x44, 0x44, 0x38}, // o + {0x00, 0xFC, 0x24, 0x24, 0x24, 0x18}, // p + {0x00, 0x18, 0x24, 0x24, 0x18, 0xFC}, // q + {0x00, 0x7C, 0x08, 0x04, 0x04, 0x08}, // r + {0x00, 0x48, 0x54, 0x54, 0x54, 0x20}, // s + {0x00, 0x04, 0x3F, 0x44, 0x40, 0x20}, // t + {0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C}, // u + {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C}, // v + {0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C}, // w + {0x00, 0x44, 0x28, 0x10, 0x28, 0x44}, // x + {0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C}, // y + {0x00, 0x44, 0x64, 0x54, 0x4C, 0x44}, // z + {0x14, 0x14, 0x14, 0x14, 0x14, 0x14}, // horiz lines +}; + +/****************************************8*16的点阵************************************/ +const unsigned char g_f8X16[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, // ! 1 + 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " 2 + 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // # 3 + 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, // $ 4 + 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, // % 5 + 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, // & 6 + 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ' 7 + 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, // ( 8 + 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, // ) 9 + 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, // * 10 + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, // + 11 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // , 12 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // - 13 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // . 14 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, // / 15 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 16 + 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 17 + 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 18 + 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 19 + 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 20 + 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 21 + 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 22 + 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 23 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 24 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 25 + 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, // : 26 + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, // ;号 27 + 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, // < 28 + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, // = 29 + 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // > 30 + 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, // ? 31 + 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, // @ 32 + 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 33 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 34 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 35 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 36 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 37 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 38 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 39 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 40 + 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 41 + 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 42 + 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 43 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 44 + 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 45 + 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 46 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 47 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 48 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 49 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 50 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 51 + 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 52 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 53 + 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 54 + 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 55 + 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 56 + 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 57 + 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 58 + 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, // [ 59 + 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, // \ 60 + 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, // ] 61 + 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^ 62 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // _ 63 + 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ` 64 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 65 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 66 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 67 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 68 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 69 + 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 70 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 71 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 72 + 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 73 + 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 74 + 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 75 + 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 76 + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 77 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 78 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 79 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 80 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 81 + 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 82 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 83 + 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 84 + 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 85 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 86 + 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 87 + 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 88 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 89 + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 90 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, // { 91 + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // | 92 + 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, // } 93 + 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ~ 94 +}; + +static const unsigned short Font7x10[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ! + 0x2800, 0x2800, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x2400, 0x2400, 0x7C00, 0x2400, 0x4800, 0x7C00, 0x4800, 0x4800, 0x0000, 0x0000, // # + 0x3800, 0x5400, 0x5000, 0x3800, 0x1400, 0x5400, 0x5400, 0x3800, 0x1000, 0x0000, // $ + 0x2000, 0x5400, 0x5800, 0x3000, 0x2800, 0x5400, 0x1400, 0x0800, 0x0000, 0x0000, // % + 0x1000, 0x2800, 0x2800, 0x1000, 0x3400, 0x4800, 0x4800, 0x3400, 0x0000, 0x0000, // & + 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x0800, 0x1000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x1000, 0x0800, // ( + 0x2000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x1000, 0x2000, // ) + 0x1000, 0x3800, 0x1000, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * + 0x0000, 0x0000, 0x1000, 0x1000, 0x7C00, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // , + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3800, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // . + 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x0000, 0x0000, // / + 0x3800, 0x4400, 0x4400, 0x5400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 0 + 0x1000, 0x3000, 0x5000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // 1 + 0x3800, 0x4400, 0x4400, 0x0400, 0x0800, 0x1000, 0x2000, 0x7C00, 0x0000, 0x0000, // 2 + 0x3800, 0x4400, 0x0400, 0x1800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 3 + 0x0800, 0x1800, 0x2800, 0x2800, 0x4800, 0x7C00, 0x0800, 0x0800, 0x0000, 0x0000, // 4 + 0x7C00, 0x4000, 0x4000, 0x7800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 5 + 0x3800, 0x4400, 0x4000, 0x7800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 6 + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, // 7 + 0x3800, 0x4400, 0x4400, 0x3800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 8 + 0x3800, 0x4400, 0x4400, 0x4400, 0x3C00, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 9 + 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ; + 0x0000, 0x0000, 0x0C00, 0x3000, 0x4000, 0x3000, 0x0C00, 0x0000, 0x0000, 0x0000, // < + 0x0000, 0x0000, 0x0000, 0x7C00, 0x0000, 0x7C00, 0x0000, 0x0000, 0x0000, 0x0000, // = + 0x0000, 0x0000, 0x6000, 0x1800, 0x0400, 0x1800, 0x6000, 0x0000, 0x0000, 0x0000, // > + 0x3800, 0x4400, 0x0400, 0x0800, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ? + 0x3800, 0x4400, 0x4C00, 0x5400, 0x5C00, 0x4000, 0x4000, 0x3800, 0x0000, 0x0000, // @ + 0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000, // A + 0x7800, 0x4400, 0x4400, 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x0000, 0x0000, // B + 0x3800, 0x4400, 0x4000, 0x4000, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // C + 0x7000, 0x4800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4800, 0x7000, 0x0000, 0x0000, // D + 0x7C00, 0x4000, 0x4000, 0x7C00, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // E + 0x7C00, 0x4000, 0x4000, 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // F + 0x3800, 0x4400, 0x4000, 0x4000, 0x5C00, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // G + 0x4400, 0x4400, 0x4400, 0x7C00, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // H + 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3800, 0x0000, 0x0000, // I + 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // J + 0x4400, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // K + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // L + 0x4400, 0x6C00, 0x6C00, 0x5400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // M + 0x4400, 0x6400, 0x6400, 0x5400, 0x5400, 0x4C00, 0x4C00, 0x4400, 0x0000, 0x0000, // N + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // O + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // P + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x5400, 0x3800, 0x0400, 0x0000, // Q + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // R + 0x3800, 0x4400, 0x4000, 0x3000, 0x0800, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // S + 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // T + 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // U + 0x4400, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x1000, 0x0000, 0x0000, // V + 0x4400, 0x4400, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // W + 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, // X + 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // Y + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // Z + 0x1800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1800, // [ + 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0000, 0x0000, /* \ */ + 0x3000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3000, // ] + 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE00, // _ + 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x3800, 0x4400, 0x3C00, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // a + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x0000, 0x0000, // b + 0x0000, 0x0000, 0x3800, 0x4400, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // c + 0x0400, 0x0400, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // d + 0x0000, 0x0000, 0x3800, 0x4400, 0x7C00, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // e + 0x0C00, 0x1000, 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // f + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x7800, // g + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // h + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // i + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xE000, // j + 0x4000, 0x4000, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4400, 0x0000, 0x0000, // k + 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // l + 0x0000, 0x0000, 0x7800, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x0000, 0x0000, // m + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // n + 0x0000, 0x0000, 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // o + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x4000, 0x4000, // p + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x0400, // q + 0x0000, 0x0000, 0x5800, 0x6400, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // r + 0x0000, 0x0000, 0x3800, 0x4400, 0x3000, 0x0800, 0x4400, 0x3800, 0x0000, 0x0000, // s + 0x2000, 0x2000, 0x7800, 0x2000, 0x2000, 0x2000, 0x2000, 0x1800, 0x0000, 0x0000, // t + 0x0000, 0x0000, 0x4400, 0x4400, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // u + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x0000, 0x0000, // v + 0x0000, 0x0000, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // w + 0x0000, 0x0000, 0x4400, 0x2800, 0x1000, 0x1000, 0x2800, 0x4400, 0x0000, 0x0000, // x + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x6000, // y + 0x0000, 0x0000, 0x7C00, 0x0800, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // z + 0x1800, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1800, // { + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, // | + 0x3000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x3000, // } + 0x0000, 0x0000, 0x0000, 0x7400, 0x4C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +static const unsigned short Font11x18[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // ! + 0x0000, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x0000, 0x1980, 0x1980, 0x1980, 0x1980, 0x7FC0, 0x7FC0, 0x1980, 0x3300, + 0x7FC0, 0x7FC0, 0x3300, 0x3300, 0x3300, 0x3300, 0x0000, 0x0000, 0x0000, // # + 0x0000, 0x1E00, 0x3F00, 0x7580, 0x6580, 0x7400, 0x3C00, 0x1E00, 0x0700, + 0x0580, 0x6580, 0x6580, 0x7580, 0x3F00, 0x1E00, 0x0400, 0x0400, 0x0000, // $ + 0x0000, 0x7000, 0xD800, 0xD840, 0xD8C0, 0xD980, 0x7300, 0x0600, 0x0C00, + 0x1B80, 0x36C0, 0x66C0, 0x46C0, 0x06C0, 0x0380, 0x0000, 0x0000, 0x0000, // % + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x3300, 0x3300, 0x1E00, 0x0C00, 0x3CC0, + 0x66C0, 0x6380, 0x6180, 0x6380, 0x3EC0, 0x1C80, 0x0000, 0x0000, 0x0000, // & + 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x0080, 0x0100, 0x0300, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0300, 0x0100, 0x0080, // ( + 0x2000, 0x1000, 0x1800, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x1800, 0x1000, 0x2000, // ) + 0x0000, 0x0C00, 0x2D00, 0x3F00, 0x1E00, 0x3300, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * + 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0xFFC0, 0xFFC0, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800, // , + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // . + 0x0000, 0x0300, 0x0300, 0x0300, 0x0600, 0x0600, 0x0600, 0x0600, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000, // / + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6D80, 0x6D80, + 0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 0 + 0x0000, 0x0600, 0x0E00, 0x1E00, 0x3600, 0x2600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // 1 + 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, 0x6180, 0x0180, 0x0300, 0x0600, + 0x0C00, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // 2 + 0x0000, 0x1C00, 0x3E00, 0x6300, 0x6300, 0x0300, 0x0E00, 0x0E00, 0x0300, + 0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 3 + 0x0000, 0x0600, 0x0E00, 0x0E00, 0x1E00, 0x1E00, 0x1600, 0x3600, 0x3600, + 0x6600, 0x7F80, 0x7F80, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // 4 + 0x0000, 0x7F00, 0x7F00, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x6380, + 0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 5 + 0x0000, 0x1E00, 0x3F00, 0x3380, 0x6180, 0x6000, 0x6E00, 0x7F00, 0x7380, + 0x6180, 0x6180, 0x6180, 0x3380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 6 + 0x0000, 0x7F80, 0x7F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0600, 0x0C00, + 0x0C00, 0x0C00, 0x0800, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000, // 7 + 0x0000, 0x1E00, 0x3F00, 0x6380, 0x6180, 0x6180, 0x2100, 0x1E00, 0x3F00, + 0x6180, 0x6180, 0x6180, 0x6180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 8 + 0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, + 0x1D80, 0x0180, 0x6180, 0x7300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 9 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800, // ; + 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0380, 0x0E00, 0x3800, 0x6000, + 0x3800, 0x0E00, 0x0380, 0x0080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // < + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7F80, 0x7F80, 0x0000, 0x0000, + 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // = + 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x7000, 0x1C00, 0x0700, 0x0180, + 0x0700, 0x1C00, 0x7000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // > + 0x0000, 0x1F00, 0x3F80, 0x71C0, 0x60C0, 0x00C0, 0x01C0, 0x0380, 0x0700, + 0x0E00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // ? + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x7180, 0x6380, 0x6F80, 0x6D80, 0x6D80, + 0x6F80, 0x6780, 0x6000, 0x3200, 0x3E00, 0x1C00, 0x0000, 0x0000, 0x0000, // @ + 0x0000, 0x0E00, 0x0E00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x3180, 0x3180, + 0x3F80, 0x3F80, 0x3180, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000, // A + 0x0000, 0x7C00, 0x7E00, 0x6300, 0x6300, 0x6300, 0x6300, 0x7E00, 0x7E00, + 0x6300, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, 0x0000, 0x0000, 0x0000, // B + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6000, + 0x6000, 0x6000, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // C + 0x0000, 0x7C00, 0x7F00, 0x6300, 0x6380, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6300, 0x6300, 0x7E00, 0x7C00, 0x0000, 0x0000, 0x0000, // D + 0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, + 0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // E + 0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, + 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, // F + 0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6380, + 0x6380, 0x6180, 0x6180, 0x3180, 0x3F80, 0x1E00, 0x0000, 0x0000, 0x0000, // G + 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x7F80, 0x7F80, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // H + 0x0000, 0x3F00, 0x3F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3F00, 0x3F00, 0x0000, 0x0000, 0x0000, // I + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, + 0x0180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // J + 0x0000, 0x60C0, 0x6180, 0x6300, 0x6600, 0x6600, 0x6C00, 0x7800, 0x7C00, + 0x6600, 0x6600, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // K + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, + 0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // L + 0x0000, 0x71C0, 0x71C0, 0x7BC0, 0x7AC0, 0x6AC0, 0x6AC0, 0x6EC0, 0x64C0, + 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000, // M + 0x0000, 0x7180, 0x7180, 0x7980, 0x7980, 0x7980, 0x6D80, 0x6D80, 0x6D80, + 0x6580, 0x6780, 0x6780, 0x6780, 0x6380, 0x6380, 0x0000, 0x0000, 0x0000, // N + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // O + 0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6180, 0x6380, 0x7F00, + 0x7E00, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, // P + 0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6580, 0x6780, 0x3300, 0x3F80, 0x1E40, 0x0000, 0x0000, 0x0000, // Q + 0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, + 0x6600, 0x6300, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // R + 0x0000, 0x0E00, 0x1F00, 0x3180, 0x3180, 0x3000, 0x3800, 0x1E00, 0x0700, + 0x0380, 0x6180, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // S + 0x0000, 0xFFC0, 0xFFC0, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // T + 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // U + 0x0000, 0x60C0, 0x60C0, 0x60C0, 0x3180, 0x3180, 0x3180, 0x1B00, 0x1B00, + 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x0400, 0x0000, 0x0000, 0x0000, // V + 0x0000, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xCCC0, 0x4C80, 0x4C80, + 0x5E80, 0x5280, 0x5280, 0x7380, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // W + 0x0000, 0xC0C0, 0x6080, 0x6180, 0x3300, 0x3B00, 0x1E00, 0x0C00, 0x0C00, + 0x1E00, 0x1F00, 0x3B00, 0x7180, 0x6180, 0xC0C0, 0x0000, 0x0000, 0x0000, // X + 0x0000, 0xC0C0, 0x6180, 0x6180, 0x3300, 0x3300, 0x1E00, 0x1E00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // Y + 0x0000, 0x3F80, 0x3F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0C00, 0x0C00, + 0x1800, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // Z + 0x0F00, 0x0F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0F00, 0x0F00, // [ + 0x0000, 0x1800, 0x1800, 0x1800, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0300, 0x0300, 0x0300, 0x0000, 0x0000, 0x0000, /* \ */ + 0x1E00, 0x1E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x1E00, 0x1E00, // ] + 0x0000, 0x0C00, 0x0C00, 0x1E00, 0x1200, 0x3300, 0x3300, 0x6180, 0x6180, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFE0, 0x0000, // _ + 0x0000, 0x3800, 0x1800, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F00, 0x3F80, 0x6180, 0x0180, + 0x1F80, 0x3F80, 0x6180, 0x6380, 0x7F80, 0x38C0, 0x0000, 0x0000, 0x0000, // a + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x0000, 0x0000, 0x0000, // b + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, + 0x6000, 0x6000, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // c + 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x1D80, 0x3F80, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0000, 0x0000, 0x0000, // d + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, + 0x7F80, 0x7F80, 0x6000, 0x7180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // e + 0x0000, 0x07C0, 0x0FC0, 0x0C00, 0x0C00, 0x7F80, 0x7F80, 0x0C00, 0x0C00, + 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // f + 0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x6380, 0x7F00, 0x3E00, // g + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6F00, 0x7F80, 0x7180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // h + 0x0000, 0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // i + 0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x4600, 0x7E00, 0x3C00, // j + 0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6180, 0x6300, 0x6600, 0x6C00, + 0x7C00, 0x7600, 0x6300, 0x6300, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // k + 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // l + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xFFC0, 0xCEC0, 0xCCC0, + 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0x0000, 0x0000, 0x0000, // m + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6F00, 0x7F80, 0x7180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // n + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, + 0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // o + 0x0000, 0x0000, 0x0000, 0x0000, 0x6E00, 0x7F00, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x6000, 0x6000, 0x6000, 0x6000, // p + 0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, + 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x0180, 0x0180, 0x0180, // q + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6700, 0x3F80, 0x3900, 0x3000, + 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x0000, 0x0000, 0x0000, // r + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F80, 0x6180, 0x6000, + 0x7F00, 0x3F80, 0x0180, 0x6180, 0x7F00, 0x1E00, 0x0000, 0x0000, 0x0000, // s + 0x0000, 0x0000, 0x0800, 0x1800, 0x1800, 0x7F00, 0x7F00, 0x1800, 0x1800, + 0x1800, 0x1800, 0x1800, 0x1800, 0x1F80, 0x0F80, 0x0000, 0x0000, 0x0000, // t + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, + 0x6180, 0x6180, 0x6180, 0x6380, 0x7F80, 0x3D80, 0x0000, 0x0000, 0x0000, // u + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x60C0, 0x3180, 0x3180, 0x3180, + 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0600, 0x0000, 0x0000, 0x0000, // v + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xDD80, 0xDD80, 0x5500, + 0x5500, 0x5500, 0x7700, 0x7700, 0x2200, 0x2200, 0x0000, 0x0000, 0x0000, // w + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x3300, 0x3300, 0x1E00, + 0x0C00, 0x0C00, 0x1E00, 0x3300, 0x3300, 0x6180, 0x0000, 0x0000, 0x0000, // x + 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x3180, 0x3300, 0x3300, + 0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x1C00, 0x7C00, 0x7000, // y + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FC0, 0x7FC0, 0x0180, 0x0300, + 0x0600, 0x0C00, 0x1800, 0x3000, 0x7FC0, 0x7FC0, 0x0000, 0x0000, 0x0000, // z + 0x0380, 0x0780, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0E00, 0x1C00, + 0x1C00, 0x0E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0780, 0x0380, // { + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, + 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, // | + 0x3800, 0x3C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0E00, 0x0700, + 0x0700, 0x0E00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3C00, 0x3800, // } + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3880, 0x7F80, + 0x4700, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; +static const unsigned short Font16x26[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [ ] + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, + 0x01C0, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [!] + 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ["] + 0x01CE, 0x03CE, 0x03DE, 0x039E, 0x039C, 0x079C, 0x3FFF, 0x7FFF, 0x0738, 0x0F38, 0x0F78, 0x0F78, 0x0E78, 0xFFFF, + 0xFFFF, 0x1EF0, 0x1CF0, 0x1CE0, 0x3CE0, 0x3DE0, 0x39E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [#] + 0x03FC, 0x0FFE, 0x1FEE, 0x1EE0, 0x1EE0, 0x1EE0, 0x1EE0, 0x1FE0, 0x0FE0, 0x07E0, 0x03F0, 0x01FC, 0x01FE, 0x01FE, + 0x01FE, 0x01FE, 0x01FE, 0x01FE, 0x3DFE, 0x3FFC, 0x0FF0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, // Ascii = [$] + 0x3E03, 0xF707, 0xE78F, 0xE78E, 0xE39E, 0xE3BC, 0xE7B8, 0xE7F8, 0xF7F0, 0x3FE0, 0x01C0, 0x03FF, 0x07FF, 0x07F3, + 0x0FF3, 0x1EF3, 0x3CF3, 0x38F3, 0x78F3, 0xF07F, 0xE03F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [%] + 0x07E0, 0x0FF8, 0x0F78, 0x1F78, 0x1F78, 0x1F78, 0x0F78, 0x0FF0, 0x0FE0, 0x1F80, 0x7FC3, 0xFBC3, 0xF3E7, 0xF1F7, + 0xF0F7, 0xF0FF, 0xF07F, 0xF83E, 0x7C7F, 0x3FFF, 0x1FEF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [&] + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ['] + 0x003F, 0x007C, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x0780, 0x0780, 0x0F80, 0x0F00, 0x0F00, 0x0F00, 0x0F00, 0x0F00, + 0x0F00, 0x0F80, 0x0780, 0x0780, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x007C, 0x003F, 0x000F, 0x0000, // Ascii = [(] + 0x7E00, 0x1F00, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x00F0, 0x00F0, 0x00F8, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, + 0x0078, 0x00F8, 0x00F0, 0x00F0, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x1F00, 0x7E00, 0x7800, 0x0000, // Ascii = [)] + 0x03E0, 0x03C0, 0x01C0, 0x39CE, 0x3FFF, 0x3F7F, 0x0320, 0x0370, 0x07F8, 0x0F78, 0x1F3C, 0x0638, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [*] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0xFFFF, + 0xFFFF, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [+] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x0380, // Ascii = [,] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFE, 0x3FFE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [-] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [.] + 0x000F, 0x000F, 0x001E, 0x001E, 0x003C, 0x003C, 0x0078, 0x0078, 0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, + 0x0780, 0x0780, 0x0F00, 0x0F00, 0x1E00, 0x1E00, 0x3C00, 0x3C00, 0x7800, 0x7800, 0xF000, 0x0000, // Ascii = [/] + 0x07F0, 0x0FF8, 0x1F7C, 0x3E3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, + 0x7C1F, 0x7C1F, 0x3C1E, 0x3E3E, 0x1F7C, 0x0FF8, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [0] + 0x00F0, 0x07F0, 0x3FF0, 0x3FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, + 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [1] + 0x0FE0, 0x3FF8, 0x3C7C, 0x003C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x007C, 0x00F8, 0x01F0, 0x03E0, 0x07C0, + 0x0780, 0x0F00, 0x1E00, 0x3E00, 0x3C00, 0x3FFE, 0x3FFE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [2] + 0x0FF0, 0x1FF8, 0x1C7C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x00F8, 0x0FF0, 0x0FF8, 0x007C, 0x003E, 0x001E, + 0x001E, 0x001E, 0x001E, 0x003E, 0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [3] + 0x0078, 0x00F8, 0x00F8, 0x01F8, 0x03F8, 0x07F8, 0x07F8, 0x0F78, 0x1E78, 0x1E78, 0x3C78, 0x7878, 0x7878, 0xFFFF, + 0xFFFF, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [4] + 0x1FFC, 0x1FFC, 0x1FFC, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FE0, 0x1FF8, 0x00FC, 0x007C, 0x003E, 0x003E, + 0x001E, 0x003E, 0x003E, 0x003C, 0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [5] + 0x01FC, 0x07FE, 0x0F8E, 0x1F00, 0x1E00, 0x3E00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFC, 0x7F3E, 0x7E1F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3E0F, 0x1E1F, 0x1F3E, 0x0FFC, 0x03F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [6] + 0x3FFF, 0x3FFF, 0x3FFF, 0x000F, 0x001E, 0x001E, 0x003C, 0x0038, 0x0078, 0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, + 0x03C0, 0x0780, 0x0F80, 0x0F80, 0x0F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [7] + 0x07F8, 0x0FFC, 0x1F3E, 0x1E1E, 0x3E1E, 0x3E1E, 0x1E1E, 0x1F3C, 0x0FF8, 0x07F0, 0x0FF8, 0x1EFC, 0x3E3E, 0x3C1F, + 0x7C1F, 0x7C0F, 0x7C0F, 0x3C1F, 0x3F3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [8] + 0x07F0, 0x0FF8, 0x1E7C, 0x3C3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x3C1F, 0x3E3F, 0x1FFF, 0x07EF, 0x001F, + 0x001E, 0x001E, 0x003E, 0x003C, 0x38F8, 0x3FF0, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [9] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [:] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x0380, // Ascii = [;] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x000F, 0x003F, 0x00FC, 0x03F0, 0x0FC0, 0x3F00, 0xFE00, + 0x3F00, 0x0FC0, 0x03F0, 0x00FC, 0x003F, 0x000F, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [<] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [=] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE000, 0xF800, 0x7E00, 0x1F80, 0x07E0, 0x01F8, 0x007E, 0x001F, + 0x007E, 0x01F8, 0x07E0, 0x1F80, 0x7E00, 0xF800, 0xE000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [>] + 0x1FF0, 0x3FFC, 0x383E, 0x381F, 0x381F, 0x001E, 0x001E, 0x003C, 0x0078, 0x00F0, 0x01E0, 0x03C0, 0x03C0, 0x07C0, + 0x07C0, 0x0000, 0x0000, 0x0000, 0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [?] + 0x03F8, 0x0FFE, 0x1F1E, 0x3E0F, 0x3C7F, 0x78FF, 0x79EF, 0x73C7, 0xF3C7, 0xF38F, 0xF38F, 0xF38F, 0xF39F, 0xF39F, + 0x73FF, 0x7BFF, 0x79F7, 0x3C00, 0x1F1C, 0x0FFC, 0x03F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [@] + 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x07F0, 0x0F78, 0x0F78, 0x0E7C, 0x1E3C, 0x1E3C, 0x3C3E, + 0x3FFE, 0x3FFF, 0x781F, 0x780F, 0xF00F, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [A] + 0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FFC, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7C, 0x3FF0, 0x3FF8, 0x3C7E, + 0x3C1F, 0x3C1F, 0x3C0F, 0x3C0F, 0x3C1F, 0x3FFE, 0x3FF8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [B] + 0x0000, 0x0000, 0x0000, 0x01FF, 0x07FF, 0x1F87, 0x3E00, 0x3C00, 0x7C00, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, + 0x7C00, 0x7C00, 0x3E00, 0x3F00, 0x1F83, 0x07FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [C] + 0x0000, 0x0000, 0x0000, 0x7FF0, 0x7FFC, 0x787E, 0x781F, 0x781F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, + 0x780F, 0x780F, 0x781F, 0x781E, 0x787E, 0x7FF8, 0x7FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [D] + 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFE, 0x3FFE, 0x3E00, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [E] + 0x0000, 0x0000, 0x0000, 0x1FFF, 0x1FFF, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FFF, 0x1FFF, 0x1E00, + 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [F] + 0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x7C00, 0x7C00, 0x7800, 0xF800, 0xF800, 0xF87F, 0xF87F, + 0x780F, 0x7C0F, 0x7C0F, 0x3E0F, 0x1F8F, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [G] + 0x0000, 0x0000, 0x0000, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7FFF, 0x7FFF, 0x7C1F, + 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [H] + 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [I] + 0x0000, 0x0000, 0x0000, 0x1FFC, 0x1FFC, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, + 0x007C, 0x007C, 0x0078, 0x0078, 0x38F8, 0x3FF0, 0x3FC0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [J] + 0x0000, 0x0000, 0x0000, 0x3C1F, 0x3C1E, 0x3C3C, 0x3C78, 0x3CF0, 0x3DE0, 0x3FE0, 0x3FC0, 0x3F80, 0x3FC0, 0x3FE0, + 0x3DF0, 0x3CF0, 0x3C78, 0x3C7C, 0x3C3E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [K] + 0x0000, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [L] + 0x0000, 0x0000, 0x0000, 0xF81F, 0xFC1F, 0xFC1F, 0xFE3F, 0xFE3F, 0xFE3F, 0xFF7F, 0xFF77, 0xFF77, 0xF7F7, 0xF7E7, + 0xF3E7, 0xF3E7, 0xF3C7, 0xF007, 0xF007, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [M] + 0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7E0F, 0x7F0F, 0x7F0F, 0x7F8F, 0x7F8F, 0x7FCF, 0x7BEF, 0x79EF, 0x79FF, + 0x78FF, 0x78FF, 0x787F, 0x783F, 0x783F, 0x781F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [N] + 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, + 0xF80F, 0x780F, 0x780F, 0x7C1F, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [O] + 0x0000, 0x0000, 0x0000, 0x3FFC, 0x3FFF, 0x3E1F, 0x3E0F, 0x3E0F, 0x3E0F, 0x3E0F, 0x3E1F, 0x3E3F, 0x3FFC, 0x3FF0, + 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [P] + 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, + 0xF80F, 0x780F, 0x780F, 0x7C1F, 0x3E3E, 0x1FFC, 0x07F8, 0x007C, 0x003F, 0x000F, 0x0003, 0x0000, // Ascii = [Q] + 0x0000, 0x0000, 0x0000, 0x3FF0, 0x3FFC, 0x3C7E, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C3C, 0x3CFC, 0x3FF0, 0x3FE0, + 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, 0x3C1E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [R] + 0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x3E0E, 0x3C00, 0x3C00, 0x3C00, 0x3E00, 0x1FC0, 0x0FF8, 0x03FE, 0x007F, + 0x001F, 0x000F, 0x000F, 0x201F, 0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [S] + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [T] + 0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, + 0x7C0F, 0x7C0F, 0x3C1E, 0x3C1E, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [U] + 0x0000, 0x0000, 0x0000, 0xF007, 0xF007, 0xF807, 0x780F, 0x7C0F, 0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1F3C, 0x1F78, + 0x0F78, 0x0FF8, 0x07F0, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [V] + 0x0000, 0x0000, 0x0000, 0xE003, 0xF003, 0xF003, 0xF007, 0xF3E7, 0xF3E7, 0xF3E7, 0x73E7, 0x7BF7, 0x7FF7, 0x7FFF, + 0x7F7F, 0x7F7F, 0x7F7E, 0x3F7E, 0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [W] + 0x0000, 0x0000, 0x0000, 0xF807, 0x7C0F, 0x3E1E, 0x3E3E, 0x1F3C, 0x0FF8, 0x07F0, 0x07E0, 0x03E0, 0x03E0, 0x07F0, + 0x0FF8, 0x0F7C, 0x1E7C, 0x3C3E, 0x781F, 0x780F, 0xF00F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [X] + 0x0000, 0x0000, 0x0000, 0xF807, 0x7807, 0x7C0F, 0x3C1E, 0x3E1E, 0x1F3C, 0x0F78, 0x0FF8, 0x07F0, 0x03E0, 0x03E0, + 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Y] + 0x0000, 0x0000, 0x0000, 0x7FFF, 0x7FFF, 0x000F, 0x001F, 0x003E, 0x007C, 0x00F8, 0x00F0, 0x01E0, 0x03E0, 0x07C0, + 0x0F80, 0x0F00, 0x1E00, 0x3E00, 0x7C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Z] + 0x07FF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, + 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x07FF, 0x07FF, 0x0000, // Ascii = [[] + 0x7800, 0x7800, 0x3C00, 0x3C00, 0x1E00, 0x1E00, 0x0F00, 0x0F00, 0x0780, 0x0780, 0x03C0, 0x03C0, 0x01E0, 0x01E0, + 0x00F0, 0x00F0, 0x0078, 0x0078, 0x003C, 0x003C, 0x001E, 0x001E, 0x000F, 0x000F, 0x0007, 0x0000, // Ascii = [\] + 0x7FF0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, + 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x7FF0, 0x7FF0, 0x0000, // Ascii = []] + 0x00C0, 0x01C0, 0x01C0, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x0778, 0x0F78, 0x0F38, 0x1E3C, 0x1E3C, 0x3C1E, 0x3C1E, + 0x380F, 0x780F, 0x7807, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [^] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, // Ascii = [_] + 0x00F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [`] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0FF8, 0x3FFC, 0x3C7C, 0x003E, 0x003E, 0x003E, 0x07FE, 0x1FFE, + 0x3E3E, 0x7C3E, 0x783E, 0x7C3E, 0x7C7E, 0x3FFF, 0x1FCF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [a] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFE, 0x3F3E, 0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3C1F, 0x3C1E, 0x3F3E, 0x3FFC, 0x3BF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [b] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x3E00, 0x3C00, 0x7C00, 0x7C00, + 0x7C00, 0x3C00, 0x3E00, 0x3E00, 0x1F87, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [c] + 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x07FF, 0x1FFF, 0x3E3F, 0x3C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x781F, + 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, 0x3E7F, 0x1FFF, 0x0FDF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [d] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03F8, 0x0FFC, 0x1F3E, 0x3E1E, 0x3C1F, 0x7C1F, 0x7FFF, 0x7FFF, + 0x7C00, 0x7C00, 0x3C00, 0x3E00, 0x1F07, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [e] + 0x01FF, 0x03E1, 0x03C0, 0x07C0, 0x07C0, 0x07C0, 0x7FFF, 0x7FFF, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, + 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [f] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EF, 0x1FFF, 0x3E7F, 0x3C1F, 0x7C1F, 0x7C1F, 0x781F, 0x781F, + 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, 0x3E7F, 0x1FFF, 0x0FDF, 0x001E, 0x001E, 0x001E, 0x387C, 0x3FF8, // Ascii = [g] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DFC, 0x3FFE, 0x3F9E, 0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, + 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [h] + 0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FE0, 0x7FE0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, + 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [i] + 0x00F8, 0x00F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FF8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, + 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F0, 0x71F0, 0x7FE0, // Ascii = [j] + 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C1F, 0x3C3E, 0x3C7C, 0x3CF8, 0x3DF0, 0x3DE0, 0x3FC0, 0x3FC0, + 0x3FE0, 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [k] + 0x7FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, + 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [l] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF79E, 0xFFFF, 0xFFFF, 0xFFFF, 0xFBE7, 0xF9E7, 0xF1C7, 0xF1C7, + 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [m] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DFC, 0x3FFE, 0x3F9E, 0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, + 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [n] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x3C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, + 0x780F, 0x780F, 0x7C1F, 0x3C1F, 0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [o] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DF8, 0x3FFE, 0x3F3E, 0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, + 0x3C0F, 0x3C0F, 0x3C1F, 0x3E1E, 0x3F3E, 0x3FFC, 0x3FF8, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, // Ascii = [p] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EE, 0x1FFE, 0x3E7E, 0x3C1E, 0x7C1E, 0x781E, 0x781E, 0x781E, + 0x781E, 0x781E, 0x7C1E, 0x7C3E, 0x3E7E, 0x1FFE, 0x0FDE, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, // Ascii = [q] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F7F, 0x1FFF, 0x1FE7, 0x1FC7, 0x1F87, 0x1F00, 0x1F00, 0x1F00, + 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [r] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x1E0E, 0x3E00, 0x3E00, 0x3F00, 0x1FE0, 0x07FC, + 0x00FE, 0x003E, 0x001E, 0x001E, 0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [s] + 0x0000, 0x0000, 0x0000, 0x0780, 0x0780, 0x0780, 0x7FFF, 0x7FFF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, + 0x0780, 0x0780, 0x0780, 0x0780, 0x07C0, 0x03FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [t] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, + 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7E, 0x3EFE, 0x1FFE, 0x0FDE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [u] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF007, 0x780F, 0x780F, 0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1E3C, + 0x0F78, 0x0F78, 0x0FF0, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [v] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF003, 0xF1E3, 0xF3E3, 0xF3E7, 0xF3F7, 0xF3F7, 0x7FF7, 0x7F77, + 0x7F7F, 0x7F7F, 0x7F7F, 0x3E3E, 0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [w] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7C0F, 0x3E1E, 0x3E3C, 0x1F3C, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, + 0x07F0, 0x07F8, 0x0FF8, 0x1E7C, 0x3E3E, 0x3C1F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [x] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF807, 0x780F, 0x7C0F, 0x3C1E, 0x3C1E, 0x1E3C, 0x1E3C, 0x1F3C, + 0x0F78, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x0780, 0x0F80, 0x7F00, // Ascii = [y] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x001F, 0x003E, 0x007C, 0x00F8, 0x01F0, 0x03E0, + 0x07C0, 0x0F80, 0x1F00, 0x1E00, 0x3C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [z] + 0x01FE, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x3F80, 0x3F80, 0x03C0, + 0x01C0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x03E0, 0x01FE, 0x007E, 0x0000, // Ascii = [{] + 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, + 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, // Ascii = [|] + 0x3FC0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x03C0, 0x01C0, 0x01E0, 0x00FE, 0x00FE, 0x01E0, + 0x01C0, 0x03C0, 0x03C0, 0x01C0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x03E0, 0x3FC0, 0x3F00, 0x0000, // Ascii = [}] + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3F07, 0x7FC7, 0x73E7, + 0xF1FF, 0xF07E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [~] +}; +static const unsigned short Font6x8[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, 0x2000, 0x0000, // ! + 0x5000, 0x5000, 0x5000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x5000, 0x5000, 0xf800, 0x5000, 0xf800, 0x5000, 0x5000, 0x0000, // # + 0x2000, 0x7800, 0xa000, 0x7000, 0x2800, 0xf000, 0x2000, 0x0000, // $ + 0xc000, 0xc800, 0x1000, 0x2000, 0x4000, 0x9800, 0x1800, 0x0000, // % + 0x4000, 0xa000, 0xa000, 0x4000, 0xa800, 0x9000, 0x6800, 0x0000, // & + 0x3000, 0x3000, 0x2000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x1000, 0x2000, 0x4000, 0x4000, 0x4000, 0x2000, 0x1000, 0x0000, // ( + 0x4000, 0x2000, 0x1000, 0x1000, 0x1000, 0x2000, 0x4000, 0x0000, // ) + 0x2000, 0xa800, 0x7000, 0xf800, 0x7000, 0xa800, 0x2000, 0x0000, // * + 0x0000, 0x2000, 0x2000, 0xf800, 0x2000, 0x2000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3000, 0x2000, 0x0000, // , + 0x0000, 0x0000, 0x0000, 0xf800, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3000, 0x0000, // . + 0x0000, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x0000, 0x0000, // / + 0x7000, 0x8800, 0x9800, 0xa800, 0xc800, 0x8800, 0x7000, 0x0000, // 0 + 0x2000, 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // 1 + 0x7000, 0x8800, 0x0800, 0x7000, 0x8000, 0x8000, 0xf800, 0x0000, // 2 + 0xf800, 0x0800, 0x1000, 0x3000, 0x0800, 0x8800, 0x7000, 0x0000, // 3 + 0x1000, 0x3000, 0x5000, 0x9000, 0xf800, 0x1000, 0x1000, 0x0000, // 4 + 0xf800, 0x8000, 0xf000, 0x0800, 0x0800, 0x8800, 0x7000, 0x0000, // 5 + 0x3800, 0x4000, 0x8000, 0xf000, 0x8800, 0x8800, 0x7000, 0x0000, // 6 + 0xf800, 0x0800, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x0000, // 7 + 0x7000, 0x8800, 0x8800, 0x7000, 0x8800, 0x8800, 0x7000, 0x0000, // 8 + 0x7000, 0x8800, 0x8800, 0x7800, 0x0800, 0x1000, 0xe000, 0x0000, // 9 + 0x0000, 0x0000, 0x2000, 0x0000, 0x2000, 0x0000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x2000, 0x0000, 0x2000, 0x2000, 0x4000, 0x0000, // ; + 0x0800, 0x1000, 0x2000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0000, // < + 0x0000, 0x0000, 0xf800, 0x0000, 0xf800, 0x0000, 0x0000, 0x0000, // = + 0x4000, 0x2000, 0x1000, 0x0800, 0x1000, 0x2000, 0x4000, 0x0000, // > + 0x7000, 0x8800, 0x0800, 0x3000, 0x2000, 0x0000, 0x2000, 0x0000, // ? + 0x7000, 0x8800, 0xa800, 0xb800, 0xb000, 0x8000, 0x7800, 0x0000, // @ + 0x2000, 0x5000, 0x8800, 0x8800, 0xf800, 0x8800, 0x8800, 0x0000, // A + 0xf000, 0x8800, 0x8800, 0xf000, 0x8800, 0x8800, 0xf000, 0x0000, // B + 0x7000, 0x8800, 0x8000, 0x8000, 0x8000, 0x8800, 0x7000, 0x0000, // C + 0xf000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0xf000, 0x0000, // D + 0xf800, 0x8000, 0x8000, 0xf000, 0x8000, 0x8000, 0xf800, 0x0000, // E + 0xf800, 0x8000, 0x8000, 0xf000, 0x8000, 0x8000, 0x8000, 0x0000, // F + 0x7800, 0x8800, 0x8000, 0x8000, 0x9800, 0x8800, 0x7800, 0x0000, // G + 0x8800, 0x8800, 0x8800, 0xf800, 0x8800, 0x8800, 0x8800, 0x0000, // H + 0x7000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // I + 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x9000, 0x6000, 0x0000, // J + 0x8800, 0x9000, 0xa000, 0xc000, 0xa000, 0x9000, 0x8800, 0x0000, // K + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0xf800, 0x0000, // L + 0x8800, 0xd800, 0xa800, 0xa800, 0xa800, 0x8800, 0x8800, 0x0000, // M + 0x8800, 0x8800, 0xc800, 0xa800, 0x9800, 0x8800, 0x8800, 0x0000, // N + 0x7000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // O + 0xf000, 0x8800, 0x8800, 0xf000, 0x8000, 0x8000, 0x8000, 0x0000, // P + 0x7000, 0x8800, 0x8800, 0x8800, 0xa800, 0x9000, 0x6800, 0x0000, // Q + 0xf000, 0x8800, 0x8800, 0xf000, 0xa000, 0x9000, 0x8800, 0x0000, // R + 0x7000, 0x8800, 0x8000, 0x7000, 0x0800, 0x8800, 0x7000, 0x0000, // S + 0xf800, 0xa800, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, // T + 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // U + 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x5000, 0x2000, 0x0000, // V + 0x8800, 0x8800, 0x8800, 0xa800, 0xa800, 0xa800, 0x5000, 0x0000, // W + 0x8800, 0x8800, 0x5000, 0x2000, 0x5000, 0x8800, 0x8800, 0x0000, // X + 0x8800, 0x8800, 0x5000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, // Y + 0xf800, 0x0800, 0x1000, 0x7000, 0x4000, 0x8000, 0xf800, 0x0000, // Z + 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7800, 0x0000, // [ + 0x0000, 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0000, 0x0000, /* \ */ + 0x7800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x7800, 0x0000, // ] + 0x2000, 0x5000, 0x8800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf800, 0x0000, // _ + 0x6000, 0x6000, 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x6000, 0x1000, 0x7000, 0x9000, 0x7800, 0x0000, // a + 0x8000, 0x8000, 0xb000, 0xc800, 0x8800, 0xc800, 0xb000, 0x0000, // b + 0x0000, 0x0000, 0x7000, 0x8800, 0x8000, 0x8800, 0x7000, 0x0000, // c + 0x0800, 0x0800, 0x6800, 0x9800, 0x8800, 0x9800, 0x6800, 0x0000, // d + 0x0000, 0x0000, 0x7000, 0x8800, 0xf800, 0x8000, 0x7000, 0x0000, // e + 0x1000, 0x2800, 0x2000, 0x7000, 0x2000, 0x2000, 0x2000, 0x0000, // f + 0x0000, 0x0000, 0x7000, 0x9800, 0x9800, 0x6800, 0x0800, 0x0000, // g + 0x8000, 0x8000, 0xb000, 0xc800, 0x8800, 0x8800, 0x8800, 0x0000, // h + 0x2000, 0x0000, 0x6000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // i + 0x1000, 0x0000, 0x1000, 0x1000, 0x1000, 0x9000, 0x6000, 0x0000, // j + 0x8000, 0x8000, 0x9000, 0xa000, 0xc000, 0xa000, 0x9000, 0x0000, // k + 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // l + 0x0000, 0x0000, 0xd000, 0xa800, 0xa800, 0xa800, 0xa800, 0x0000, // m + 0x0000, 0x0000, 0xb000, 0xc800, 0x8800, 0x8800, 0x8800, 0x0000, // n + 0x0000, 0x0000, 0x7000, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // o + 0x0000, 0x0000, 0xb000, 0xc800, 0xc800, 0xb000, 0x8000, 0x0000, // p + 0x0000, 0x0000, 0x6800, 0x9800, 0x9800, 0x6800, 0x0800, 0x0000, // q + 0x0000, 0x0000, 0xb000, 0xc800, 0x8000, 0x8000, 0x8000, 0x0000, // r + 0x0000, 0x0000, 0x7800, 0x8000, 0x7000, 0x0800, 0xf000, 0x0000, // s + 0x2000, 0x2000, 0xf800, 0x2000, 0x2000, 0x2800, 0x1000, 0x0000, // t + 0x0000, 0x0000, 0x8800, 0x8800, 0x8800, 0x9800, 0x6800, 0x0000, // u + 0x0000, 0x0000, 0x8800, 0x8800, 0x8800, 0x5000, 0x2000, 0x0000, // v + 0x0000, 0x0000, 0x8800, 0x8800, 0xa800, 0xa800, 0x5000, 0x0000, // w + 0x0000, 0x0000, 0x8800, 0x5000, 0x2000, 0x5000, 0x8800, 0x0000, // x + 0x0000, 0x0000, 0x8800, 0x8800, 0x7800, 0x0800, 0x8800, 0x0000, // y + 0x0000, 0x0000, 0xf800, 0x1000, 0x2000, 0x4000, 0xf800, 0x0000, // z + 0x1000, 0x2000, 0x2000, 0x4000, 0x2000, 0x2000, 0x1000, 0x0000, // { + 0x2000, 0x2000, 0x2000, 0x0000, 0x2000, 0x2000, 0x2000, 0x0000, // | + 0x4000, 0x2000, 0x2000, 0x1000, 0x2000, 0x2000, 0x4000, 0x0000, // } + 0x4000, 0xa800, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +FontDef Font_7x10 = {7, 10, Font7x10}; +FontDef Font_6x8 = {6, 8, Font6x8}; +FontDef Font_11x18 = {11, 18, Font11x18}; +FontDef Font_16x26 = {16, 26, Font16x26}; \ No newline at end of file diff --git a/src/vendor/test/ultrasonic/ssd1306_fonts.h b/src/vendor/test/ultrasonic/ssd1306_fonts.h new file mode 100644 index 0000000000000000000000000000000000000000..21afb48aa124f6e4579b1520082c9d3571f381db --- /dev/null +++ b/src/vendor/test/ultrasonic/ssd1306_fonts.h @@ -0,0 +1,58 @@ +/* + MIT License + + Copyright (c) 2018, Alexey Dynda + + 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. +*/ +/** + * @file ssd1306_fonts.h Fonts for monochrome/rgb oled display + */ + +#ifndef SSD1306_FONTS_H +#define SSD1306_FONTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup LCD_FONTS FONTS: Supported LCD fonts + * @{ + */ + +extern const unsigned char g_f6X8[][6]; +extern const unsigned char g_f8X16[]; + +typedef struct { + const unsigned char FontWidth; /*!< Font width in pixels */ + unsigned char FontHeight; /*!< Font height in pixels */ + const unsigned short *data; /*!< Pointer to data font data array */ +} FontDef; + +extern FontDef Font_7x10; +extern FontDef Font_6x8; +extern FontDef Font_11x18; +extern FontDef Font_16x26; + +#ifdef __cplusplus +} +#endif + +#endif // SSD1306_FONTS_H \ No newline at end of file diff --git a/src/vendor/test/wifiap/CMakeLists.txt b/src/vendor/test/wifiap/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ce01622a9600866015f59147131db028bb7ed02d --- /dev/null +++ b/src/vendor/test/wifiap/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/softap_sample.c" PARENT_SCOPE) diff --git a/src/vendor/test/wifiap/README.md b/src/vendor/test/wifiap/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c1eb723ee403c9a14159b4817440b83c6d6f9d07 --- /dev/null +++ b/src/vendor/test/wifiap/README.md @@ -0,0 +1,94 @@ +# wifiap + +## 1.1 介绍 + +**功能介绍:** 实现手机等其他设备连接核心板热点,案例核心板热点需要设置为SSID:H, 密码:12345678。 + +**硬件概述:** 核心板。硬件搭建要求如图所示: + + image-20240401152853303 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 手机WLAN搜索热点H,搜索成功后,输入密码:”12345678“进行连接。 + + ![image-20240418174657120](../../../docs/pic/wifiap/image-20240418174657120.png) + +## 1.4 接口介绍 + +### 1.4.1 wifi_softap_enable() + +| **定义:** | errcode_t wifi_softap_enable(const softap_config_stru *config); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 开启SoftAP | +| **参数:** | config:SoftAp的配置 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\middleware\services\wifi\wifi_hotspot.h | + +### 1.4.2 netifapi_netif_set_addr() + +| **定义:** | err_t netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置网络接口的IP地址 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | open_source\lwip\lwip_v2.1.3\src\include\lwip\netifapi.h | + +### 1.4.3 netifapi_dhcps_start() + +| **定义:** | err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 启动dhcp服务 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | open_source\lwip\lwip_v2.1.3\src\include\lwip\netifapi.h | + +## 1.5 具体实现 + + 步骤一:初始化WiFi。 + + 步骤二:启动WiFi AP模式。 + + 步骤三:配置DHCP服务器。 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”wifiap“。 + + ![image-20240402193714218](../../../docs/pic/wifidemo/image-20240402193714218.png) + +- 步骤二:将open_cfbb\vendor\hihspark\wifiap文件里面内容拷贝到**步骤一创建的Sample文件夹中”wifiap“**下。 + + ![image-20240418174149411](../../../docs/pic/wifiap/image-20240418174149411.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support WIFIAP Sample”,点击Save,关闭弹窗。 + + image-20240401153033024image-20240401153046561image-20240418174332350 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七:手机WLAN搜索热点H,搜索成功后,输入密码:”12345678“进行连接。 + + ![image-20240418174657120](../../../docs/pic/wifiap/image-20240418174657120.png) diff --git a/src/vendor/test/wifiap/softap_sample.c b/src/vendor/test/wifiap/softap_sample.c new file mode 100644 index 0000000000000000000000000000000000000000..6494688fdaa3f49f06ca962c5419e616c98f5e7a --- /dev/null +++ b/src/vendor/test/wifiap/softap_sample.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "stdlib.h" +#include "uart.h" +#include "cmsis_os2.h" +#include "soc_osal.h" +#include "app_init.h" + +#define WIFI_SOFTAP_TASK_PRIO 24 +#define WIFI_TASK_STACK_SIZE 0x2000 +#define WIFI_IFNAME_MAX_SIZE 16 + +static errcode_t example_softap_function(void) +{ + /* SoftAp SSID */ + char ssid[WIFI_MAX_SSID_LEN] = "H"; + + char pre_shared_key[WIFI_MAX_KEY_LEN] = "12345678"; + softap_config_stru hapd_conf = {0}; + + char ifname[WIFI_IFNAME_MAX_SIZE] = "ap0"; /* WiFi SoftAP 网络设备名,SDK默认是ap0, 以实际名称为准 */ + struct netif *netif_p = NULL; + ip4_addr_t st_gw = {0}; + ip4_addr_t st_ipaddr = {0}; + ip4_addr_t st_netmask = {0}; + IP4_ADDR(&st_ipaddr, 192, 168, 63, 1); /* IP地址设置:192.168.63.1 */ + IP4_ADDR(&st_netmask, 255, 255, 255, 0); /* 子网掩码设置:255.255.255.0 */ + IP4_ADDR(&st_gw, 192, 168, 63, 2); /* 网关地址设置:192.168.63.2 */ + + PRINT("SoftAP try enable.\r\n"); + + (void)memcpy_s(hapd_conf.ssid, sizeof(hapd_conf.ssid), ssid, sizeof(ssid)); + (void)memcpy_s(hapd_conf.pre_shared_key, WIFI_MAX_KEY_LEN, pre_shared_key, WIFI_MAX_KEY_LEN); + + hapd_conf.security_type = WIFI_SEC_TYPE_WPA2_WPA_PSK_MIX; /* 个人级的WPA和WPA2混合 */ + hapd_conf.channel_num = 6; /* 6:工作信道设置为6信道 */ + + /* 启动SoftAp接口 */ + if (wifi_softap_enable(&hapd_conf) != ERRCODE_SUCC) { + PRINT("softap enable fail.\r\n"); + return ERRCODE_FAIL; + } + + /* 配置DHCP服务器 */ + netif_p = netif_find(ifname); + if (netif_p == NULL) { + PRINT("find netif fail.\r\n", ifname); + (void)wifi_softap_disable(); + return ERRCODE_FAIL; + } + if (netifapi_netif_set_addr(netif_p, &st_ipaddr, &st_netmask, &st_gw) != ERR_OK) { + PRINT("set addr() fail.\r\n"); + (void)wifi_softap_disable(); + return ERRCODE_FAIL; + } + if (netifapi_dhcps_start(netif_p, NULL, 0) != ERR_OK) { + PRINT("dhcps start() fail.\r\n"); + (void)wifi_softap_disable(); + return ERRCODE_FAIL; + } + PRINT("SoftAp start success.\r\n"); + return ERRCODE_SUCC; +} + +static int demo_init(const char *arg) +{ + unused(arg); + + (void)osal_msleep(5000); /* 延时5s,等待wifi初始化完毕 */ + /* 启SoftAP功能和DHCP服务 */ + if (example_softap_function() != ERRCODE_SUCC) { + return -1; + } + return 0; +} + +static void example_wifi_softap_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)demo_init, 0, "WiFiSoftAPTask", WIFI_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, WIFI_SOFTAP_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the example_wifi_softap_entry. */ +app_run(example_wifi_softap_entry); \ No newline at end of file diff --git a/src/vendor/test/wifista/CMakeLists.txt b/src/vendor/test/wifista/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..6669d6d00d06050c8f0282c4529c548633ea79f6 --- /dev/null +++ b/src/vendor/test/wifista/CMakeLists.txt @@ -0,0 +1 @@ +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/sta_sample.c" PARENT_SCOPE) diff --git a/src/vendor/test/wifista/README.md b/src/vendor/test/wifista/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b476ab9d7a32de7829b3877ac178704678fc9145 --- /dev/null +++ b/src/vendor/test/wifista/README.md @@ -0,0 +1,121 @@ +# wifista + +## 1.1 介绍 + +**功能介绍:** 实现核心板连接路由器热点或者手机热点,案例中手机或者路由器热点需要设置为SSID:H, 密码:12345678。 + +**硬件概述:** 核心板。硬件搭建要求如图所示: + + image-20240401152853303 + +## 1.2 约束与限制 + +### 1.2.1 支持应用运行的芯片和开发板 + + 本示例支持开发板:HiHope_NearLink_DK3863E_V01 + +### 1.2.2 支持API版本、SDK版本 + + 本示例支持版本号:1.10.100 + +### 1.2.3 支持IDE版本、支持配套工具版本 + + 本示例仅支持IDE版本号:0.0.1;支持配套工具版本:DevTools_CFBB_V1.0.11及以上 + +## 1.3 效果预览 + + 连接上热点后,可以看到addr:192.168.43.194为本机IP地址,server_id:192.168.43.1为服务端IP地址,使用AT+PING=“服务端IP地址”。 + + ![image-20240418172420858](../../../docs/pic/wifista/image-20240418172420858.png)![image-20240418172612581](../../../docs/pic/wifista/image-20240418172612581.png) + +## 1.4 接口介绍 + +### 1.4.1 wifi_sta_enable() + +| **定义:** | errcode_t wifi_sta_enable(void); | +| ------------ | ----------------------------------------------- | +| **功能:** | 开启SoftAP | +| **参数:** | config:SoftAp的配置 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\middleware\services\wifi\wifi_hotspot.h | + +### 1.4.2 netifapi_netif_set_addr() + +| **定义:** | err_t netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 设置网络接口的IP地址 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | open_source\lwip\lwip_v2.1.3\src\include\lwip\netifapi.h | + +### 1.4.3 netifapi_dhcps_start() + +| **定义:** | err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 启动dhcp服务 | +| **返回值:** | ERROCODE_SUCC:成功 Other:失败 | +| **依赖:** | open_source\lwip\lwip_v2.1.3\src\include\lwip\netifapi.h | + +### 1.4.4 wifi_sta_scan() + +| **定义:** | errcode_t wifi_sta_scan(void); | +| ------------ | ---------------------------------------------- | +| **功能:** | 进行全信道基础扫描 | +| **参数:** | void类型 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\middleware\services\wifi\wifi_device.h | + +### 1.4.5 wifi_sta_connect() + +| **定义:** | errcode_t wifi_sta_connect(const wifi_sta_config_stru *config); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 进行连接网络 | +| **参数:** | config:连接的网络参数 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\middleware\services\wifi\wifi_device.h | + +### 1.4.6 wifi_sta_get_ap_info() + +| **定义:** | errcode_t wifi_sta_get_ap_info(wifi_linked_info_stru *result); | +| ------------ | ------------------------------------------------------------ | +| **功能:** | 获取station连接的网络状态 | +| **参数:** | result:连接状态 | +| **返回值:** | ERRCODE_SUCC:成功 Other:失败 | +| **依赖:** | include\middleware\services\radar\radar_service.h | + +## 1.5 具体实现 + + 步骤一:初始化wifi。 + + 步骤二:启动STA扫描,获取等待连接的网络。 + + 步骤三:DHCP获取IP地址,并PING主机。 + +## 1.6 实验流程 + +- 步骤一:在open_cfbb\src\application\samples文件夹新建一个sample文件夹,在peripheral上右键选择ZeroScript-Sample,创建Sample文件夹,例如名称”wifista“。 + + ![image-20240402193714218](../../../docs/pic/wifidemo/image-20240402193714218.png) + +- 步骤二:将open_cfbb\vendor\hihspark\wifista文件里面内容拷贝到**步骤一创建的Sample文件夹中”wifista“**下。 + + ![image-20240418171824704](../../../docs/pic/wifista/image-20240418171824704.png) + +- 步骤三:点击如下图标,选择KConfig,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“support WIFISTA Sample”,点击Save,关闭弹窗。 + + image-20240401153033024image-20240401153046561image-20240418172048117 + +- 步骤四:选择“工程配置”,在"compiler_bin_path"栏选择编译工具包路径。 + + ![image-20240205110042240](../../../docs/pic/timer/image-20240205110042240-17119401758319.png) + +- 步骤五:点击DevEco Device Tool工具“Rebuild”按键”。 + + ![image-20240205105926768](../../../docs/pic/timer/image-20240205105926768-17119401758317.png) + +- 步骤六:点击DevEco Device Tool工具“Upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板reset键),将程序烧录到开发板中。 + + ![image-20240205110327591](../../../docs/pic/timer/image-20240205110327591-171194017584310.png) + +- 步骤七:连接上热点后,可以看到addr:192.168.43.194为本机IP地址,server_id:192.168.43.1为服务端IP地址,使用AT+PING=“服务端IP地址”。 + + ![image-20240418172420858](../../../docs/pic/wifista/image-20240418172420858.png)![image-20240418172612581](../../../docs/pic/wifista/image-20240418172612581.png) diff --git a/src/vendor/test/wifista/sta_sample.c b/src/vendor/test/wifista/sta_sample.c new file mode 100644 index 0000000000000000000000000000000000000000..dae20b8b4b5daddd64b4bf991db800e5c3c7e18b --- /dev/null +++ b/src/vendor/test/wifista/sta_sample.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2024 HiSilicon Technologies CO., 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 "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "stdlib.h" +#include "uart.h" +#include "misc.h" +#include "soc_osal.h" +#include "app_init.h" + +#define WIFI_STA_TASK_PRIO 24 +#define WIFI_STA_TASK_STACK_SIZE 0x2000 +#define WIFI_IFNAME_MAX_SIZE 16 +#define WIFI_SCAN_AP_LIMIT 64 +#define WIFI_CONN_STATUS_MAX_GET_TIMES 5 /* 启动连接之后,判断是否连接成功的最大尝试次数 */ +#define DHCP_BOUND_STATUS_MAX_GET_TIMES 20 /* 启动DHCP Client端功能之后,判断是否绑定成功的最大尝试次数 */ +#define WIFI_STA_IP_MAX_GET_TIMES 5 /* 判断是否获取到IP的最大尝试次数 */ + +/***************************************************************************** + STA 扫描-关联 sample用例 +*****************************************************************************/ +static errcode_t example_get_match_network(const char *expected_ssid, + const char *key, + wifi_sta_config_stru *expected_bss) +{ + uint32_t num = WIFI_SCAN_AP_LIMIT; /* 64:扫描到的Wi-Fi网络数量 */ + uint32_t bss_index = 0; + + /* 获取扫描结果 */ + uint32_t scan_len = sizeof(wifi_scan_info_stru) * WIFI_SCAN_AP_LIMIT; + wifi_scan_info_stru *result = osal_kmalloc(scan_len, OSAL_GFP_ATOMIC); + if (result == NULL) { + return ERRCODE_MALLOC; + } + + memset_s(result, scan_len, 0, scan_len); + if (wifi_sta_get_scan_info(result, &num) != ERRCODE_SUCC) { + osal_kfree(result); + return ERRCODE_FAIL; + } + + /* 筛选扫描到的Wi-Fi网络,选择待连接的网络 */ + for (bss_index = 0; bss_index < num; bss_index++) { + if (strlen(expected_ssid) == strlen(result[bss_index].ssid)) { + if (memcmp(expected_ssid, result[bss_index].ssid, strlen(expected_ssid)) == 0) { + break; + } + } + } + + /* 未找到待连接AP,可以继续尝试扫描或者退出 */ + if (bss_index >= num) { + osal_kfree(result); + return ERRCODE_FAIL; + } + /* 找到网络后复制网络信息和接入密码 */ + if (memcpy_s(expected_bss->ssid, WIFI_MAX_SSID_LEN, result[bss_index].ssid, WIFI_MAX_SSID_LEN) != EOK) { + osal_kfree(result); + return ERRCODE_MEMCPY; + } + if (memcpy_s(expected_bss->bssid, WIFI_MAC_LEN, result[bss_index].bssid, WIFI_MAC_LEN) != EOK) { + osal_kfree(result); + return ERRCODE_MEMCPY; + } + expected_bss->security_type = result[bss_index].security_type; + if (memcpy_s(expected_bss->pre_shared_key, WIFI_MAX_KEY_LEN, key, strlen(key)) != EOK) { + osal_kfree(result); + return ERRCODE_MEMCPY; + } + expected_bss->ip_type = DHCP; /* IP类型为动态DHCP获取 */ + osal_kfree(result); + return ERRCODE_SUCC; +} + +static errcode_t example_sta_function(void) +{ + char ifname[WIFI_IFNAME_MAX_SIZE + 1] = "wlan0"; /* WiFi STA 网络设备名,SDK默认是wlan0, 以实际名称为准 */ + wifi_sta_config_stru expected_bss = {0}; /* 连接请求信息 */ + const char expected_ssid[] = "H"; + const char key[] = "12345678"; /* 待连接的网络接入密码 */ + struct netif *netif_p = NULL; + wifi_linked_info_stru wifi_status; + uint8_t index = 0; + + (void)osal_msleep(5000); /* 延时5s,等待wifi初始化完毕 */ + printf("STA try enable.\r\n"); + /* 创建STA */ + if (wifi_sta_enable() != ERRCODE_SUCC) { + printf("sta enbale fail !\r\n"); + return ERRCODE_FAIL; + } + + do { + printf("Start Scan !\r\n"); + (void)osal_msleep(1000); /* 每次触发扫描至少间隔1s */ + /* 启动STA扫描 */ + if (wifi_sta_scan() != ERRCODE_SUCC) { + printf("STA scan fail, try again !\r\n"); + continue; + } + + (void)osal_msleep(3000); /* 延时3s, 等待扫描完成 */ + + /* 获取待连接的网络 */ + if (example_get_match_network(expected_ssid, key, &expected_bss) != ERRCODE_SUCC) { + printf("Can not find AP, try again !\r\n"); + continue; + } + + printf("STA try connect.\r\n"); + /* 启动连接 */ + if (wifi_sta_connect(&expected_bss) != ERRCODE_SUCC) { + continue; + } + + /* 检查网络是否连接成功 */ + for (index = 0; index < WIFI_CONN_STATUS_MAX_GET_TIMES; index++) { + (void)osal_msleep(500); /* 延时500ms */ + memset_s(&wifi_status, sizeof(wifi_linked_info_stru), 0, sizeof(wifi_linked_info_stru)); + if (wifi_sta_get_ap_info(&wifi_status) != ERRCODE_SUCC) { + continue; + } + if (wifi_status.conn_state == WIFI_CONNECTED) { + break; + } + } + + if (wifi_status.conn_state == WIFI_CONNECTED) { + break; /* 连接成功退出循环 */ + } + } while (1); + + printf("STA DHCP start.\r\n"); + /* DHCP获取IP地址 */ + netif_p = netifapi_netif_find(ifname); + if (netif_p == NULL) { + return ERRCODE_FAIL; + } + + if (netifapi_dhcp_start(netif_p) != ERR_OK) { + printf("STA DHCP Fail.\r\n"); + return ERRCODE_FAIL; + } + + for (uint8_t i = 0; i < DHCP_BOUND_STATUS_MAX_GET_TIMES; i++) { + (void)osal_msleep(500); /* 延时500ms */ + if (netifapi_dhcp_is_bound(netif_p) == ERR_OK) { + printf("STA DHCP bound success.\r\n"); + break; + } + } + + for (uint8_t i = 0; i < WIFI_STA_IP_MAX_GET_TIMES; i++) { + (void)osal_msleep(10); /* 延时10ms */ + if (netif_p->ip_addr.u_addr.ip4.addr != 0) { + printf("STA IP %u.%u.%u.%u\r\n", (netif_p->ip_addr.u_addr.ip4.addr & 0x000000ff), + (netif_p->ip_addr.u_addr.ip4.addr & 0x0000ff00) >> 8, + (netif_p->ip_addr.u_addr.ip4.addr & 0x00ff0000) >> 16, + (netif_p->ip_addr.u_addr.ip4.addr & 0xff000000) >> 24); + netifapi_netif_common(netif_p, dhcp_clients_info_show, NULL); + if (netifapi_dhcp_start(netif_p) != 0) { + printf("STA DHCP Fail.\r\n"); + return ERRCODE_FAIL; + } + + /* 连接成功 */ + printf("STA connect success.\r\n"); + return ERRCODE_SUCC; + } + } + + printf("STA connect fail.\r\n"); + return ERRCODE_FAIL; +} + +int demo_init(void *param) +{ + param = param; + example_sta_function(); + return 0; +} + +static void wifistaentry(void) +{ + osal_task *task_handle = NULL; + + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)demo_init, 0, "WiFiStaTask", WIFI_STA_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, WIFI_STA_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the example_wifi_sta_entry. */ +app_run(wifistaentry); \ No newline at end of file