打包keil_MDK的工程

This commit is contained in:
不吃油炸鸡
2026-02-26 11:25:38 +08:00
parent ef38c0f19f
commit aae7ce5938
1200 changed files with 0 additions and 832317 deletions

View File

@@ -1,10 +0,0 @@
#include "beep.h"
#include "tim.h"
void beep_open(void) {
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4); // 启动PWM通道4用于蜂鸣器
}
void beep_close(void) {
HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_4); // 停止PWM通道4
}

View File

@@ -1,18 +0,0 @@
#ifndef __BEEP_H__
#define __BEEP_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
void beep_open(void);
void beep_close(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,190 +0,0 @@
#include "BL24C02.h"
#include "i2c.h"
// hardware settings
#include "lcd_init.h"
typedef struct {
uint8_t backlight_level; // 0-100
uint8_t key_sound_enable; // 0:disable, 1:enable
uint8_t language_select; // 0:English, 1:Chinese
uint16_t rotation; // 0, 90, 180, 270
} SysSettings_T;
static SysSettings_T sys_settings = {
.backlight_level = 50,
.key_sound_enable = 1,
.language_select = 0,
.rotation = 0
};
static void BL24C02_Write(uint8_t addr, uint16_t length, uint8_t buff[])
{
HAL_I2C_Mem_Write(&hi2c1, BL24C02_ADDRESS<<1, addr, I2C_MEMADD_SIZE_8BIT, buff, length, 10);
}
static void BL24C02_Read(uint8_t addr, uint8_t length, uint8_t buff[])
{
HAL_I2C_Mem_Read(&hi2c1, BL24C02_ADDRESS<<1, addr, I2C_MEMADD_SIZE_8BIT, buff, length, 10);
}
static void delay_ms(uint32_t ms)
{
HAL_Delay(ms);
}
/******************************************
EEPROM Data description:
[0x00]: 0x55 for check
[0x01]: 0xAA for check
[0x10]: user backlight_level setting
[0x11]: user key_sound_enable setting
[0x12]: user language_select setting
[0x13-14]: user rotation setting
[0x20-]: update command storage area, "update\r\n"
*******************************************/
// to check the Data is right and the EEPROM is working, 0-ok, 1-erro
uint8_t EEPROM_Init_Check(void)
{
uint8_t check_buff[2];
delay_ms(10);
BL24C02_Read(0,2,check_buff);
if(check_buff[0] == 0x55 && check_buff[1] == 0xAA)
{
return 0;//check OK
}
else
{
check_buff[0] = 0x55;
check_buff[1] = 0xAA;
delay_ms(10);
BL24C02_Write(0,2,check_buff);
memset(check_buff,0,2);
delay_ms(10);
BL24C02_Read(0,2,check_buff);
if(check_buff[0] == 0x55 && check_buff[1] == 0xAA)
return 0;//check ok
}
return 1;//check erro
}
// to Save the settings
void EEPROM_SysSetting_Save(void)
{
uint8_t buff[5];
buff[0] = sys_settings.backlight_level;
buff[1] = sys_settings.key_sound_enable;
buff[2] = sys_settings.language_select;
buff[3] = (uint8_t)(sys_settings.rotation & 0x00FF);
buff[4] = (uint8_t)((sys_settings.rotation >> 8) & 0x00FF);
BL24C02_Write(0x10,5,buff);
}
// to Get the settings
void EEPROM_SysSetting_Get(void)
{
uint8_t buff[5];
BL24C02_Read(0x10,5,buff);
// 判断是否在范围内
if(buff[0] <= 100)
sys_settings.backlight_level = buff[0];
else
sys_settings.backlight_level = 60;
if(buff[1] <= 1)
sys_settings.key_sound_enable = buff[1];
else
sys_settings.key_sound_enable = 1;
if(buff[2] <= 1)
sys_settings.language_select = buff[2];
else
sys_settings.language_select = 0;
uint16_t rotation = (uint16_t)buff[3] | ((uint16_t)buff[4] << 8);
if(rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270)
sys_settings.rotation = rotation;
else
sys_settings.rotation = 180;
}
// to write the update command
void EEPROM_UpdateCommand_Write(bool is_update)
{
if(is_update) {
char cmd[] = "update\r\n";
BL24C02_Write(0x20, strlen(cmd), (uint8_t *)cmd);
} else {
char cmd[] = "-nope-\r\n";
BL24C02_Write(0x20, strlen(cmd), (uint8_t *)cmd);
}
}
// to check the update command
bool EEPROM_UpdateCommand_Check(void)
{
char cmd[10] = {0};
BL24C02_Read(0x20, 8, (uint8_t *)cmd);
if(strcmp(cmd, "update\r\n") == 0) {
return true;
} else {
return false;
}
}
// Set functions
void Sys_Set_BacklightLevel(uint8_t level)
{
if(level <= 100 && level >= 0) {
sys_settings.backlight_level = level;
LCD_Set_Light(level);
}
}
void Sys_Set_KeySoundEnable(bool enable)
{
if(enable) {
sys_settings.key_sound_enable = 1;
} else {
sys_settings.key_sound_enable = 0;
}
}
void Sys_Set_LanguageSelect(uint8_t lang)
{
if(lang <= 1) {
sys_settings.language_select = lang;
}
}
void Sys_Set_Rotation(uint16_t rotation)
{
if(rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270) {
sys_settings.rotation = rotation;
LCD_SetRotation(rotation);
}
}
// Get functions
uint8_t Sys_Get_BacklightLevel(void)
{
return sys_settings.backlight_level;
}
uint8_t Sys_Get_KeySoundEnable(void)
{
return sys_settings.key_sound_enable;
}
uint8_t Sys_Get_LanguageSelect(void)
{
return sys_settings.language_select;
}
uint16_t Sys_Get_Rotation(void)
{
return sys_settings.rotation;
}

View File

@@ -1,30 +0,0 @@
#ifndef __BL24C02_H
#define __BL24C02_H
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#define BL24C02_ADDRESS 0x50
uint8_t EEPROM_Init_Check(void);
void EEPROM_SysSetting_Save(void);
void EEPROM_SysSetting_Get(void);
void EEPROM_UpdateCommand_Write(bool is_update);
bool EEPROM_UpdateCommand_Check(void);
// set functions
void Sys_Set_BacklightLevel(uint8_t level);
void Sys_Set_KeySoundEnable(bool enable);
void Sys_Set_LanguageSelect(uint8_t lang);
void Sys_Set_Rotation(uint16_t rotation);
// get functions
uint8_t Sys_Get_BacklightLevel(void);
uint8_t Sys_Get_KeySoundEnable(void);
uint8_t Sys_Get_LanguageSelect(void);
uint16_t Sys_Get_Rotation(void);
#endif

View File

@@ -1,61 +0,0 @@
#include "gate.h"
#include "math.h"
uint8_t gate_status = HIGH_CUR; // Default status
void Gate_Port_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(EN1_PORT, EN1_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(EN2_PORT, EN2_PIN, GPIO_PIN_RESET);
/*Configure GPIO pin : PB3 */
GPIO_InitStruct.Pin = EN1_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(EN1_PORT, &GPIO_InitStruct);
/*Configure GPIO pin : PB3 */
GPIO_InitStruct.Pin = EN2_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(EN2_PORT, &GPIO_InitStruct);
}
void flow_route_selection(uint8_t selection)
{
if(selection > HIGH_CUR)
selection = HIGH_CUR; // Invalid selection
if(selection < LOW_CUR)
selection = LOW_CUR;
if(selection == HIGH_CUR)
{
HAL_GPIO_WritePin(EN1_PORT, EN1_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(EN2_PORT, EN2_PIN, GPIO_PIN_RESET);
}
else if(selection == MID_CUR)
{
HAL_GPIO_WritePin(EN1_PORT, EN1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(EN2_PORT, EN2_PIN, GPIO_PIN_SET);
}
else if(selection == LOW_CUR)
{
HAL_GPIO_WritePin(EN1_PORT, EN1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(EN2_PORT, EN2_PIN, GPIO_PIN_RESET);
}
gate_status = selection; // Update the status
}
uint8_t Gate_get_status(void)
{
return gate_status;
}

View File

@@ -1,32 +0,0 @@
#ifndef __GATE_H__
#define __GATE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
#include "adc.h"
// EN1
#define EN1_PORT GPIOB
#define EN1_PIN GPIO_PIN_3
// EN2
#define EN2_PORT GPIOA
#define EN2_PIN GPIO_PIN_15
// Flow route selection
#define HIGH_CUR 3
#define MID_CUR 2
#define LOW_CUR 1
void Gate_Port_Init(void);
void flow_route_selection(uint8_t selection);
uint8_t Gate_get_status(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,276 +0,0 @@
/*
* key.c
*
* 按键驱动:
* - 支持多键注册GPIO低/高有效)
* - 去抖、长按、连发
* - 事件队列DOWN/UP/CLICK/LONG/REPEAT
* - 掩码查询当前稳定按下状态,支持多键同时
*
* Created on: 2025-12-02
*/
#include "key.h"
#include "sys.h"
#include "cmsis_os.h" // 若无OS可移除
#include <string.h>
/* 若有OS则用OS tick否则用HAL tick */
#if OS_SUPPORT
#define key_get_tick() ((uint32_t)osKernelGetTickCount())
#else
#define key_get_tick() ((uint32_t)HAL_GetTick())
#endif
#define TICK_DIFF(now, then) ((uint32_t)((uint32_t)(now) - (uint32_t)(then)))
/* 按键槽结构体 */
typedef struct {
GPIO_TypeDef* port; // gpio port
uint16_t pin; // gpio pin
uint8_t active_high; // 高电平有效
uint8_t registered; // 是否已注册
uint8_t raw_pressed; // 原始按下状态
uint8_t stable_pressed; // 稳定按下状态
uint32_t debounce_tick; // 消抖计时
uint8_t long_reported; // 长按事件是否上报
uint32_t press_tick; // 按下时刻
uint32_t last_repeat_tick; // 上次连发时刻
} key_slot_t;
/* 全局按键管理结构体 */
static struct {
uint8_t mode;
key_timing_t timing;
uint32_t long_enable_mask;
key_slot_t slot[KEY_ID_MAX];
uint32_t raw_mask;
uint32_t stable_mask;
} g_key = {
.mode = (KEY_MODE_REPORT_DOWN_UP | KEY_MODE_CLICK_ON_RELEASE | KEY_MODE_LONG_ONCE),
.timing = { .debounce_ms = 5, .long_ms = 500, .repeat_ms = 100 },
.long_enable_mask = 0,
.raw_mask = 0,
.stable_mask = 0,
};
/**
* @brief 注册GPIO按键
* @param id 按键ID
* @param port GPIO端口
* @param pin GPIO引脚
* @param active_high 引脚高电平有效
*/
bool Key_RegisterGPIO(key_id_t id, GPIO_TypeDef* port, uint16_t pin, uint8_t active_high)
{
if(id >= KEY_ID_MAX || port == NULL) return false;
key_slot_t* k = &g_key.slot[id];
k->port = port;
k->pin = pin;
k->active_high = active_high ? 1 : 0;
k->registered = 1;
k->raw_pressed = 0;
k->stable_pressed = 0;
k->debounce_tick = key_get_tick();
k->long_reported = 0;
k->press_tick = 0;
k->last_repeat_tick = 0;
return true;
}
/**
* @brief 设置按键模式
* @param mode_flags 模式标志位
*/
void Key_SetMode(uint8_t mode_flags) { g_key.mode = mode_flags; }
/**
* @brief 获取按键模式
* @return 当前模式标志位
*/
uint8_t Key_GetMode(void) { return g_key.mode; }
/**
* @brief 设置允许长按/连发的按键掩码
* @param mask 按键掩码
*/
void Key_SetLongEnableMask(uint32_t mask) { g_key.long_enable_mask = mask & KEY_ALL_MASK; }
/**
* @brief 获取允许长按/连发的按键掩码
* @return 按键掩码
*/
uint32_t Key_GetLongEnableMask(void) { return g_key.long_enable_mask; }
/**
* @brief 获取当前稳定按下的按键掩码
* @return 按键掩码
*/
uint32_t Key_GetPressedMask(void) { return g_key.stable_mask; }
/**
* @brief 获取当前原始按下的按键掩码
* @return 按键掩码
*/
uint32_t Key_GetRawMask(void) { return g_key.raw_mask; }
/**
* @brief 设置时序参数
* @param t 指向时序参数结构体的指针
*/
void Key_SetTiming(const key_timing_t* t)
{
if(!t) return;
if(t->debounce_ms) g_key.timing.debounce_ms = t->debounce_ms;
if(t->repeat_ms) g_key.timing.repeat_ms = t->repeat_ms;
if(t->long_ms) g_key.timing.long_ms = t->long_ms;
}
/**
* @brief 获取按键按下状态(考虑高/低有效)
* @param port GPIO端口
* @param pin GPIO引脚
* @param active_high 引脚高电平有效
*/
static inline uint8_t read_pressed(GPIO_TypeDef* port, uint16_t pin, uint8_t active_high)
{
GPIO_PinState s = HAL_GPIO_ReadPin(port, pin);
return active_high ? (s == GPIO_PIN_SET) : (s == GPIO_PIN_RESET);
}
/**
* @brief 扫描一次,若有事件则通过 out_evt 返回
* @param out_evt 指向事件对象的指针(非空)
* @return true 有事件false 无事件
* @note 每次调用仅返回一个事件优先级顺序DOWN/UP -> CLICK -> LONG -> REPEAT,
* @note 返回事件后可以检测掩码查看是否同时按下键用于组合逻辑Key_GetPressedMask();
*/
bool Key_Scan(key_event_t* out_evt)
{
if(!out_evt) return false;
uint32_t now = key_get_tick();
/* 采样原始状态 */
uint32_t new_raw_mask = 0;
for(uint8_t i=0; i<KEY_ID_MAX; ++i){
key_slot_t* k = &g_key.slot[i];
if(!k->registered) continue;
uint8_t raw = read_pressed(k->port, k->pin, k->active_high);
if(raw != k->raw_pressed){
k->raw_pressed = raw;
k->debounce_tick = now;
}
if(raw) new_raw_mask |= KEY_BIT(i);
}
g_key.raw_mask = new_raw_mask;
/* 边沿与事件(优先返回最先发现的一个事件) */
for(uint8_t i=0; i<KEY_ID_MAX; ++i){
key_slot_t* k = &g_key.slot[i];
if(!k->registered) continue;
/* 去抖窗口内不改变稳定态 */
if(TICK_DIFF(now, k->debounce_tick) < g_key.timing.debounce_ms){
continue;
}
uint8_t stable_now = k->raw_pressed;
if(stable_now != k->stable_pressed){
/* 稳定边沿 */
k->stable_pressed = stable_now;
if(stable_now){
/* DOWN */
g_key.stable_mask |= KEY_BIT(i);
k->press_tick = now;
k->last_repeat_tick = now;
k->long_reported = 0;
if(g_key.mode & KEY_MODE_REPORT_DOWN_UP){
out_evt->id = (key_id_t)i;
out_evt->type = KEY_EVT_DOWN;
return true;
}
}else{
/* UP */
g_key.stable_mask &= ~KEY_BIT(i);
if(g_key.mode & KEY_MODE_REPORT_DOWN_UP){
out_evt->id = (key_id_t)i;
out_evt->type = KEY_EVT_UP;
return true;
}
if((g_key.mode & KEY_MODE_CLICK_ON_RELEASE) && !k->long_reported){
out_evt->id = (key_id_t)i;
out_evt->type = KEY_EVT_CLICK;
/* 复位长按标记 */
k->long_reported = 0;
return true;
}
/* 复位长按标记 */
k->long_reported = 0;
}
}
}
/* 长按/连发(按下且允许时) */
for(uint8_t i=0; i<KEY_ID_MAX; ++i){
key_slot_t* k = &g_key.slot[i];
if(!k->registered || !k->stable_pressed) continue;
if(!(g_key.long_enable_mask & KEY_BIT(i))) continue;
uint32_t held = TICK_DIFF(now, k->press_tick);
/* 首次长按 */
if(!k->long_reported && (held >= g_key.timing.long_ms)){
k->long_reported = 1;
if(g_key.mode & (KEY_MODE_LONG_ONCE | KEY_MODE_REPEAT)){
out_evt->id = (key_id_t)i;
out_evt->type = KEY_EVT_LONG;
k->last_repeat_tick = now;
return true;
}
}
/* 连发 */
if(k->long_reported && (g_key.mode & KEY_MODE_REPEAT)){
if(TICK_DIFF(now, k->last_repeat_tick) >= g_key.timing.repeat_ms){
k->last_repeat_tick = now;
out_evt->id = (key_id_t)i;
out_evt->type = KEY_EVT_REPEAT;
return true;
}
}
}
return false;
}
/* 初始化GPIO */
static void Key_Port_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin : PA0 */
GPIO_InitStruct.Pin = KEYB_PIN | KEYY_PIN | KEYL_PIN | KEYR_PIN | KEYN_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEYB_PORT, &GPIO_InitStruct);
}
/* 注册默认按键 */
static bool Key_RegisterDefaultKeys(void)
{
bool ok = true;
ok &= Key_RegisterGPIO(KEY_ID_B, KEYB_PORT, KEYB_PIN, 0);
ok &= Key_RegisterGPIO(KEY_ID_Y, KEYY_PORT, KEYY_PIN, 0);
ok &= Key_RegisterGPIO(KEY_ID_L, KEYL_PORT, KEYL_PIN, 0);
ok &= Key_RegisterGPIO(KEY_ID_R, KEYR_PORT, KEYR_PIN, 0);
ok &= Key_RegisterGPIO(KEY_ID_N, KEYN_PORT, KEYN_PIN, 0);
return ok;
}
/* 初始化按键 */
void Key_Init(void)
{
memset(&g_key.slot[0], 0, sizeof(g_key.slot));
g_key.raw_mask = 0;
g_key.stable_mask = 0;
Key_Port_Init();
Key_RegisterDefaultKeys();
Key_SetMode(KEY_MODE_CLICK_ON_RELEASE | KEY_MODE_LONG_ONCE | KEY_MODE_REPEAT);
Key_SetLongEnableMask(KEY_BIT(KEY_ID_Y) | KEY_BIT(KEY_ID_N));
}

View File

@@ -1,103 +0,0 @@
#ifndef __KEY_H__
#define __KEY_H__
#ifdef __cplusplus
extern "C" {
#endif
#pragma once
#include "main.h"
#include <stdint.h>
#include <stdbool.h>
// 时间参数单位ms
#define KEY_LONG_THRESHOLD_MS 500 // 长按判定时间
#define KEY_REPEAT_INTERVAL_MS 150 // 连发间隔时间
#define KEY_DEBOUNCE_MS 3 // 消抖时间
/* 掩码工具(位索引即 key_id_t */
#define KEY_BIT(id) (1U << (uint8_t)(id))
#define KEY_ALL_MASK ((uint32_t)((KEY_ID_MAX >= 32) ? 0xFFFFFFFFu : ((1u << KEY_ID_MAX) - 1)))
//KEYB
#define KEYB_PORT GPIOA
#define KEYB_PIN GPIO_PIN_0
//KEYN
#define KEYN_PORT GPIOA
#define KEYN_PIN GPIO_PIN_4
//KEYL
#define KEYL_PORT GPIOA
#define KEYL_PIN GPIO_PIN_3
//KEYR
#define KEYR_PORT GPIOA
#define KEYR_PIN GPIO_PIN_2
//KEYY
#define KEYY_PORT GPIOA
#define KEYY_PIN GPIO_PIN_1
/**
* @brief 按键ID与掩码位索引一致
*/
typedef enum {
KEY_ID_B = 0, // KEYB
KEY_ID_Y, // KEYY
KEY_ID_L, // KEYL
KEY_ID_R, // KEYR
KEY_ID_N, // KEYN
KEY_ID_MAX
} key_id_t;
/**
* @brief 事件类型
*/
typedef enum {
KEY_EVT_NONE = 0,
KEY_EVT_DOWN = 1, // 去抖后稳定按下
KEY_EVT_UP = 2, // 去抖后稳定释放
KEY_EVT_CLICK = 3, // 短按(一次按下->释放,且未触发长按)
KEY_EVT_LONG = 4, // 达到长按阈值触发一次
KEY_EVT_REPEAT = 5 // 长按连发周期事件
} key_evt_type_t;
/**
* @brief 事件对象
*/
typedef struct {
key_id_t id;
key_evt_type_t type;
} key_event_t;
/**
* @brief 扫描模式(可用位或"|"组合)
*/
typedef enum {
KEY_MODE_REPORT_DOWN_UP = 0x01, // 上报 DOWN/UP
KEY_MODE_CLICK_ON_RELEASE = 0x02, // 释放时若未长按,上报 CLICK
KEY_MODE_LONG_ONCE = 0x04, // 达到阈值上报一次 LONG
KEY_MODE_REPEAT = 0x08 // 达到阈值后周期性上报 REPEAT
} key_mode_t;
/**
* @brief 时序参数单位ms可运行时修改
*/
typedef struct {
uint16_t debounce_ms; // 消抖时间,建议 3~20
uint16_t long_ms; // 长按判定时间,建议 400~800
uint16_t repeat_ms; // 连发间隔,建议 80~200
} key_timing_t;
void Key_Init(void);
bool Key_Scan(key_event_t* out_evt);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,611 +0,0 @@
#include "lcd.h"
#include "lcd_init.h"
#include "lcdfont.h"
#include "spi.h"
#include "cmsis_os.h"
extern osSemaphoreId_t DMA_SemaphoreHandle;
/******************************************************************************
函数说明:在指定区域填充颜色
入口数据xsta,ysta 起始坐标
xend,yend 终止坐标
color 要填充的颜色
返回值: 无
******************************************************************************/
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
{
u16 i,j;
LCD_Address_Set(xsta, ysta,xend-1, yend-1);//设置显示范围
for(i=ysta;i<yend;i++)
{
for(j=xsta;j<xend;j++)
{
LCD_WR_DATA(color);
}
}
}
/******************************************************************************
函数说明:在指定区域填充颜色
入口数据xsta,ysta 起始坐标
xend,yend 终止坐标
color pixel map
返回值: 无
******************************************************************************/
void LCD_Color_Render_Async(u16 xsta, u16 ysta, u16 xend, u16 yend, u16 *color_p)
{
// 1. 设置地址 (命令是 8 位的,此时 SPI 必须是 8 位模式)
LCD_Address_Set(xsta, ysta, xend, yend);
// 计算总数据量
uint32_t count = (xend - xsta + 1) * (yend - ysta + 1);
// 2. 安全切换到 16-bit 模式
// 必须先关 SPI改寄存器再开 SPI
__HAL_SPI_DISABLE(&hspi2);
hspi2.Instance->CR1 |= SPI_CR1_DFF; // 置位 DFF启用 16 位数据帧
__HAL_SPI_ENABLE(&hspi2);
// 3. 启动 DMA 传输
HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)color_p, count);
}
static void *lcd_ready_cb = NULL;
// 设置通知的回调函数
void LCD_Set_Flush_Complete_Callback(void *cb)
{
// 保存回调指针
lcd_ready_cb = cb;
}
// DMA 传输完成中断回调
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi->Instance == SPI2)
{
// 1. 死等 SPI 总线发完最后 1 bit
while (hspi->Instance->SR & SPI_FLAG_BSY);
// 2. 安全切回 8-bit 模式 (为下一次发送命令做准备)
__HAL_SPI_DISABLE(hspi);
hspi->Instance->CR1 &= ~SPI_CR1_DFF; // 清除 DFF回退到 8 位
__HAL_SPI_ENABLE(hspi);
// 3. 通知 LVGL 渲染结束,执行回调函数
if (lcd_ready_cb) {
LCD_CallbackFunc_t func = (LCD_CallbackFunc_t)lcd_ready_cb;
func();
}
}
}
/******************************************************************************
函数说明:在指定位置画点
入口数据x,y 画点坐标
color 点的颜色
返回值: 无
******************************************************************************/
void LCD_DrawPoint(u16 x,u16 y,u16 color)
{
LCD_Address_Set(x,y,x,y);//设置光标位置
LCD_WR_DATA(color);
}
/******************************************************************************
函数说明:画线
入口数据x1,y1 起始坐标
x2,y2 终止坐标
color 线的颜色
返回值: 无
******************************************************************************/
void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1; //计算坐标增量
delta_y=y2-y1;
uRow=x1;//画线起点坐标
uCol=y1;
if(delta_x>0)incx=1; //设置单步方向
else if (delta_x==0)incx=0;//垂直线
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if (delta_y==0)incy=0;//水平线
else {incy=-1;delta_y=-delta_y;}
if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
else distance=delta_y;
for(t=0;t<distance+1;t++)
{
LCD_DrawPoint(uRow,uCol,color);//画点
xerr+=delta_x;
yerr+=delta_y;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
/******************************************************************************
函数说明:画矩形
入口数据x1,y1 起始坐标
x2,y2 终止坐标
color 矩形的颜色
返回值: 无
******************************************************************************/
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color)
{
LCD_DrawLine(x1,y1,x2,y1,color);
LCD_DrawLine(x1,y1,x1,y2,color);
LCD_DrawLine(x1,y2,x2,y2,color);
LCD_DrawLine(x2,y1,x2,y2,color);
}
/******************************************************************************
函数说明:画圆
入口数据x0,y0 圆心坐标
r 半径
color 圆的颜色
返回值: 无
******************************************************************************/
void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color)
{
int a,b;
a=0;b=r;
while(a<=b)
{
LCD_DrawPoint(x0-b,y0-a,color); //3
LCD_DrawPoint(x0+b,y0-a,color); //0
LCD_DrawPoint(x0-a,y0+b,color); //1
LCD_DrawPoint(x0-a,y0-b,color); //2
LCD_DrawPoint(x0+b,y0+a,color); //4
LCD_DrawPoint(x0+a,y0-b,color); //5
LCD_DrawPoint(x0+a,y0+b,color); //6
LCD_DrawPoint(x0-b,y0+a,color); //7
a++;
if((a*a+b*b)>(r*r))//判断要画的点是否过远
{
b--;
}
}
}
/******************************************************************************
函数说明:显示汉字串
入口数据x,y显示坐标
*s 要显示的汉字串
fc 字的颜色
bc 字的背景色
sizey 字号 可选 16 24 32
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
while(*s!=0)
{
if(sizey==12) LCD_ShowChinese12x12(x,y,s,fc,bc,sizey,mode);
else if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);
else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);
else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);
else return;
s+=2;
x+=sizey;
}
}
/******************************************************************************
函数说明显示单个12x12汉字
入口数据x,y显示坐标
*s 要显示的汉字
fc 字的颜色
bc 字的背景色
sizey 字号
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
u8 i,j,m=0;
u16 k;
u16 HZnum;//汉字数目
u16 TypefaceNum;//一个字符所占字节大小
u16 x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
HZnum=sizeof(tfont12)/sizeof(typFNT_GB12); //统计汉字数目
for(k=0;k<HZnum;k++)
{
if((tfont12[k].Index[0]==*(s))&&(tfont12[k].Index[1]==*(s+1)))
{
LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
for(i=0;i<TypefaceNum;i++)
{
for(j=0;j<8;j++)
{
if(!mode)//非叠加方式
{
if(tfont12[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizey==0)
{
m=0;
break;
}
}
else//叠加方式
{
if(tfont12[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//画一个点
x++;
if((x-x0)==sizey)
{
x=x0;
y++;
break;
}
}
}
}
}
continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
}
}
/******************************************************************************
函数说明显示单个16x16汉字
入口数据x,y显示坐标
*s 要显示的汉字
fc 字的颜色
bc 字的背景色
sizey 字号
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
u8 i,j,m=0;
u16 k;
u16 HZnum;//汉字数目
u16 TypefaceNum;//一个字符所占字节大小
u16 x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
HZnum=sizeof(tfont16)/sizeof(typFNT_GB16); //统计汉字数目
for(k=0;k<HZnum;k++)
{
if ((tfont16[k].Index[0]==*(s))&&(tfont16[k].Index[1]==*(s+1)))
{
LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
for(i=0;i<TypefaceNum;i++)
{
for(j=0;j<8;j++)
{
if(!mode)//非叠加方式
{
if(tfont16[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizey==0)
{
m=0;
break;
}
}
else//叠加方式
{
if(tfont16[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//画一个点
x++;
if((x-x0)==sizey)
{
x=x0;
y++;
break;
}
}
}
}
}
continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
}
}
/******************************************************************************
函数说明显示单个24x24汉字
入口数据x,y显示坐标
*s 要显示的汉字
fc 字的颜色
bc 字的背景色
sizey 字号
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
u8 i,j,m=0;
u16 k;
u16 HZnum;//汉字数目
u16 TypefaceNum;//一个字符所占字节大小
u16 x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
HZnum=sizeof(tfont24)/sizeof(typFNT_GB24); //统计汉字数目
for(k=0;k<HZnum;k++)
{
if ((tfont24[k].Index[0]==*(s))&&(tfont24[k].Index[1]==*(s+1)))
{
LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
for(i=0;i<TypefaceNum;i++)
{
for(j=0;j<8;j++)
{
if(!mode)//非叠加方式
{
if(tfont24[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizey==0)
{
m=0;
break;
}
}
else//叠加方式
{
if(tfont24[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//画一个点
x++;
if((x-x0)==sizey)
{
x=x0;
y++;
break;
}
}
}
}
}
continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
}
}
/******************************************************************************
函数说明显示单个32x32汉字
入口数据x,y显示坐标
*s 要显示的汉字
fc 字的颜色
bc 字的背景色
sizey 字号
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
u8 i,j,m=0;
u16 k;
u16 HZnum;//汉字数目
u16 TypefaceNum;//一个字符所占字节大小
u16 x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
HZnum=sizeof(tfont32)/sizeof(typFNT_GB32); //统计汉字数目
for(k=0;k<HZnum;k++)
{
if ((tfont32[k].Index[0]==*(s))&&(tfont32[k].Index[1]==*(s+1)))
{
LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
for(i=0;i<TypefaceNum;i++)
{
for(j=0;j<8;j++)
{
if(!mode)//非叠加方式
{
if(tfont32[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizey==0)
{
m=0;
break;
}
}
else//叠加方式
{
if(tfont32[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//画一个点
x++;
if((x-x0)==sizey)
{
x=x0;
y++;
break;
}
}
}
}
}
continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
}
}
/******************************************************************************
函数说明:显示单个字符
入口数据x,y显示坐标
num 要显示的字符
fc 字的颜色
bc 字的背景色
sizey 字号
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode)
{
u8 temp,sizex,t,m=0;
u16 i,TypefaceNum;//一个字符所占字节大小
u16 x0=x;
sizex=sizey/2;
TypefaceNum=(sizex/8+((sizex%8)?1:0))*sizey;
num=num-' '; //得到偏移后的值
LCD_Address_Set(x,y,x+sizex-1,y+sizey-1); //设置光标位置
for(i=0;i<TypefaceNum;i++)
{
if(sizey==12)temp=ascii_1206[num][i]; //调用6x12字体
else if(sizey==16)temp=ascii_1608[num][i]; //调用8x16字体
else if(sizey==24)temp=ascii_2412[num][i]; //调用12x24字体
else if(sizey==32)temp=ascii_3216[num][i]; //调用16x32字体
else return;
for(t=0;t<8;t++)
{
if(!mode)//非叠加模式
{
if(temp&(0x01<<t))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizex==0)
{
m=0;
break;
}
}
else//叠加模式
{
if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//画一个点
x++;
if((x-x0)==sizex)
{
x=x0;
y++;
break;
}
}
}
}
}
/******************************************************************************
函数说明:显示字符串
入口数据x,y显示坐标
*p 要显示的字符串
fc 字的颜色
bc 字的背景色
sizey 字号
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode)
{
while(*p!='\0')
{
LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
x+=sizey/2;
p++;
}
}
/******************************************************************************
函数说明:显示数字
入口数据m底数n指数
返回值: 无
******************************************************************************/
u32 mypow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
/******************************************************************************
函数说明:显示整数变量
入口数据x,y显示坐标
num 要显示整数变量
len 要显示的位数
fc 字的颜色
bc 字的背景色
sizey 字号
返回值: 无
******************************************************************************/
void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey)
{
u8 t,temp;
u8 enshow=0;
u8 sizex=sizey/2;
for(t=0;t<len;t++)
{
temp=(num/mypow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
LCD_ShowChar(x+t*sizex,y,' ',fc,bc,sizey,0);
continue;
}else enshow=1;
}
LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
}
}
/******************************************************************************
函数说明:显示两位小数变量
入口数据x,y显示坐标
num 要显示小数变量
len 要显示的位数
fc 字的颜色
bc 字的背景色
sizey 字号
返回值: 无
******************************************************************************/
void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey)
{
u8 t,temp,sizex;
u16 num1;
sizex=sizey/2;
num1=num*100;
for(t=0;t<len;t++)
{
temp=(num1/mypow(10,len-t-1))%10;
if(t==(len-2))
{
LCD_ShowChar(x+(len-2)*sizex,y,'.',fc,bc,sizey,0);
t++;
len+=1;
}
LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
}
}
/******************************************************************************
函数说明:显示图片
入口数据x,y起点坐标
length 图片长度
width 图片宽度
pic[] 图片数组
返回值: 无
******************************************************************************/
void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[])
{
u16 i,j;
u32 k=0;
LCD_Address_Set(x,y,x+length-1,y+width-1);
for(i=0;i<length;i++)
{
for(j=0;j<width;j++)
{
LCD_WR_DATA8(pic[k*2]);
LCD_WR_DATA8(pic[k*2+1]);
k++;
}
}
}

View File

@@ -1,58 +0,0 @@
#ifndef __LCD_H
#define __LCD_H
#include "sys.h"
typedef void (*LCD_CallbackFunc_t)(void); // 定义LCD完成DMA刷新回调函数类型
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color);//指定区域填充颜色
void LCD_Set_Flush_Complete_Callback(void *cb);
void LCD_Color_Render_Async(u16 xsta, u16 ysta, u16 xend, u16 yend, u16 *color_p);
void LCD_DrawPoint(u16 x,u16 y,u16 color);//在指定位置画一个点
void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color);//在指定位置画一条线
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color);//在指定位置画一个矩形
void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color);//在指定位置画一个圆
void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示汉字串
void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个12x12汉字
void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个16x16汉字
void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个24x24汉字
void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode);//显示单个32x32汉字
void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode);//显示一个字符
void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode);//显示字符串
u32 mypow(u8 m,u8 n);//求幂
void LCD_ShowIntNum(u16 x,u16 y,u16 num,u8 len,u16 fc,u16 bc,u8 sizey);//显示整数变量
void LCD_ShowFloatNum1(u16 x,u16 y,float num,u8 len,u16 fc,u16 bc,u8 sizey);//显示两位小数变量
void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[]);//显示图片
//画笔颜色
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40 //棕色
#define BRRED 0XFC07 //棕红色
#define GRAY 0X8430 //灰色
#define DARKBLUE 0X01CF //深蓝色
#define LIGHTBLUE 0X7D7C //浅蓝色
#define GRAYBLUE 0X5458 //灰蓝色
#define LIGHTGREEN 0X841F //浅绿色
#define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色)
#endif

View File

@@ -1,339 +0,0 @@
#include "lcd_init.h"
#include "spi.h"
#include "tim.h"
uint8_t LCD_ROTATION = 0; // 0, 90, 180, 270
uint8_t OFFSET_X = 0;
uint8_t OFFSET_Y = 0;
/******************************************************************************
函数说明LCD端口初始化
入口数据:无
返回值: 无
******************************************************************************/
void LCD_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStructure.Pin = RES_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;//速度50MHz
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB
HAL_GPIO_WritePin(GPIOB, RES_PIN, GPIO_PIN_SET);
GPIO_InitStructure.Pin = CS_PIN|DC_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;//速度50MHz
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOB
HAL_GPIO_WritePin(GPIOA, CS_PIN|DC_PIN, GPIO_PIN_SET);
}
/******************************************************************************
函数说明LCD串行数据写入函数(software SPI)
入口数据dat 要写入的串行数据
返回值: 无
******************************************************************************/
void LCD_Writ_Bus(u8 dat)
{
//hard SPI
HAL_SPI_Transmit(&hspi2,&dat,1,1);
//soft SPI
/*
u8 i;
for(i=0;i<8;i++)
{
LCD_SCLK_Clr();
if(dat&0x80)
{
LCD_MOSI_Set();
}
else
{
LCD_MOSI_Clr();
}
LCD_SCLK_Set();
dat<<=1;
}
*/
}
/******************************************************************************
函数说明LCD写入数据
入口数据dat 写入的数据
返回值: 无
******************************************************************************/
void LCD_WR_DATA8(u8 dat)
{
LCD_Writ_Bus(dat);
}
/******************************************************************************
函数说明LCD写入数据
入口数据dat 写入的数据
返回值: 无
******************************************************************************/
void LCD_WR_DATA(u16 dat)
{
// LCD_Writ_Bus(dat>>8);
// LCD_Writ_Bus(dat);
uint8_t temp[2];
temp[0]=(dat>>8)&0xff;
temp[1]=dat&0xff;
HAL_SPI_Transmit(&hspi2,temp,2,1);
}
/******************************************************************************
函数说明LCD写入命令
入口数据dat 写入的命令
返回值: 无
******************************************************************************/
void LCD_WR_REG(u8 dat)
{
LCD_DC_Clr();//写命令
LCD_Writ_Bus(dat);
LCD_DC_Set();//写数据
}
/******************************************************************************
函数说明:设置起始和结束地址
入口数据x1,x2 设置列的起始和结束地址
y1,y2 设置行的起始和结束地址
返回值: 无
******************************************************************************/
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
{
LCD_WR_REG(0x2a);//列地址设置
LCD_WR_DATA(x1 + OFFSET_X);
LCD_WR_DATA(x2 + OFFSET_X);
LCD_WR_REG(0x2b);//行地址设置
LCD_WR_DATA(y1 + OFFSET_Y);
LCD_WR_DATA(y2 + OFFSET_Y);
LCD_WR_REG(0x2c);//储存器写
}
/******************************************************************************
函数说明LCD调节背光
入口数据dc,占空比,5%~100%
返回值: 无
******************************************************************************/
void LCD_Set_Light(uint8_t dc)
{
if(dc>=5 && dc<=100)
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_3,dc*PWM_PERIOD/100);
}
/******************************************************************************
函数说明LCD关闭背光
入口数据:无
返回值: 无
******************************************************************************/
void LCD_Close_Light(void)
{
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_3,0);
//HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_3);
}
/******************************************************************************
函数说明LCD开启背光
入口数据:无
返回值: 无
******************************************************************************/
void LCD_Open_Light(void)
{
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);
}
/******************************************************************************
函数说明ST7789 SLEEP IN
入口数据:无
返回值: 无
******************************************************************************/
void LCD_ST7789_SleepIn(void)
{
LCD_WR_REG(0x10);
HAL_Delay(100);
}
/******************************************************************************
函数说明ST7789 SLEEP OUT
入口数据:无
返回值: 无
******************************************************************************/
void LCD_ST7789_SleepOut(void)
{
LCD_WR_REG(0x11);
HAL_Delay(100);
}
/******************************************************************************
函数说明:设置屏幕旋转方向
入口数据rotation 0, 90, 180, 270
返回值: 无
******************************************************************************/
void LCD_SetRotation(uint16_t rotation) {
LCD_WR_REG(0x36); // Memory Data Access Control
switch(rotation) {
case 0:
OFFSET_X = 0;
OFFSET_Y = 0;
LCD_WR_DATA8(0x00);
break;
case 180:
OFFSET_X = 0;
OFFSET_Y = 80;
LCD_WR_DATA8(0xC0);
break;
case 90:
OFFSET_X = 0;
OFFSET_Y = 0;
LCD_WR_DATA8(0x70);
break;
case 270:
OFFSET_X = 80;
OFFSET_Y = 0;
LCD_WR_DATA8(0xA0);
break;
default:
OFFSET_X = 0;
OFFSET_Y = 0;
LCD_WR_DATA8(0x00);
break;
}
}
/******************************************************************************
函数说明LCD初始化
入口数据:无
返回值: 无
******************************************************************************/
void LCD_Init(void)
{
LCD_GPIO_Init();//初始化GPIO
LCD_CS_Clr(); //chip select
LCD_RES_Clr(); //复位
HAL_Delay(100);
LCD_RES_Set();
HAL_Delay(100);
// 1. 退出睡眠模式 (Exit Sleep Mode)
LCD_WR_REG(0x11);
HAL_Delay(120);
// 2. 设置显示方向 (Memory Data Access Control)
LCD_SetRotation(LCD_ROTATION);
// 3. 设置像素格式 (Interface Pixel Format)
// 0x55 表示 16位色 (RGB565)。如果设置为0x66 (18位色),颜色会不正确。
LCD_WR_REG(0x3A);
LCD_WR_DATA8(0x55);
// 4. Porch 设置 (时序控制)
// 控制行扫描的前后肩时间,通常不需要修改。
LCD_WR_REG(0xB2);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x33);
LCD_WR_DATA8(0x33);
// 5. Gate 控制 (Gate Control)
// 【色彩关键】设置VGH和VGL电压影响屏幕的对比度和上下视角。
// 0x35是一个比较通用的值。如果屏幕有垂直方向的串扰或闪烁可以尝试修改这个值。
LCD_WR_REG(0xB7);
LCD_WR_DATA8(0x35);
// 6. VCOM 设置 (VCOM Setting)
// 【色彩关键】这是非常重要的参数,直接影响显示质量,特别是对比度和闪烁。
// 0x19 是一个参考值,可以在 0x10 到 0x30 之间尝试,找到最稳定的值。
LCD_WR_REG(0xBB);
LCD_WR_DATA8(0x19);
// 7. LCM 控制 (LCM Control)
LCD_WR_REG(0xC0);
LCD_WR_DATA8(0x2C);
// 8. VDV 和 VRH 命令使能
LCD_WR_REG(0xC2);
LCD_WR_DATA8(0x01);
// 9. VRH 设置 (VRH Set)
// 【色彩关键】影响驱动电压,可以微调屏幕的整体亮度和功耗。
LCD_WR_REG(0xC3);
LCD_WR_DATA8(0x12);
// 10. VDV 设置 (VDV Set)
// 通常保持默认值。
LCD_WR_REG(0xC4);
LCD_WR_DATA8(0x20);
// 11. 帧率控制 (Frame Rate Control)
// 0x0F 通常对应 60Hz 左右的刷新率。如果屏幕闪烁可以尝试减小这个值例如0x14但会增加功耗。
LCD_WR_REG(0xC6);
LCD_WR_DATA8(0x0F);
// 12. 电源控制 (Power Control)
LCD_WR_REG(0xD0);
LCD_WR_DATA8(0xA6);
LCD_WR_DATA8(0xA1);
// 13. 正 Gamma 校正 (Positive Voltage Gamma Control)
// 【色彩关键】这是调整颜色和灰阶表现最核心的部分!
// 这14个字节定义了从暗到亮的灰阶曲线。修改这些值可以显著改变色彩的饱和度、对比度和过渡平滑度。
LCD_WR_REG(0xE0);
LCD_WR_DATA8(0xD0);
LCD_WR_DATA8(0x04);
LCD_WR_DATA8(0x0D);
LCD_WR_DATA8(0x11);
LCD_WR_DATA8(0x13);
LCD_WR_DATA8(0x2B);
LCD_WR_DATA8(0x3F);
LCD_WR_DATA8(0x54);
LCD_WR_DATA8(0x4C);
LCD_WR_DATA8(0x18);
LCD_WR_DATA8(0x0D);
LCD_WR_DATA8(0x0B);
LCD_WR_DATA8(0x1F);
LCD_WR_DATA8(0x23);
// 14. 负 Gamma 校正 (Negative Voltage Gamma Control)
// 【色彩关键】与正Gamma同样重要两者需要配合调整以达到最佳效果。
LCD_WR_REG(0xE1);
LCD_WR_DATA8(0xD0);
LCD_WR_DATA8(0x04);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x11);
LCD_WR_DATA8(0x13);
LCD_WR_DATA8(0x2C);
LCD_WR_DATA8(0x3F);
LCD_WR_DATA8(0x44);
LCD_WR_DATA8(0x51);
LCD_WR_DATA8(0x2F);
LCD_WR_DATA8(0x1F);
LCD_WR_DATA8(0x1F);
LCD_WR_DATA8(0x20);
LCD_WR_DATA8(0x23);
// 15. 开启颜色反转 (Display Inversion On)
LCD_WR_REG(0x21);
// 16. 开启显示 (Display On)
LCD_WR_REG(0x29);
}

View File

@@ -1,68 +0,0 @@
#ifndef __LCD_INIT_H
#define __LCD_INIT_H
#include "sys.h"
extern uint8_t LCD_ROTATION;
extern uint8_t OFFSET_X;
extern uint8_t OFFSET_Y;
#define LCD_W 240
#define LCD_H 240
//-----------------LCD端口定义----------------
#define SCLK_PORT GPIOB
#define SCLK_PIN GPIO_PIN_13
#define SDA_PORT GPIOB
#define SDA_PIN GPIO_PIN_15
#define RES_PORT GPIOB
#define RES_PIN GPIO_PIN_12
#define DC_PORT GPIOA
#define DC_PIN GPIO_PIN_9
#define CS_PORT GPIOA
#define CS_PIN GPIO_PIN_8
#define BLK_PORT GPIOA
#define BLK_PIN GPIO_PIN_10
#define LCD_SCLK_Clr() HAL_GPIO_WritePin(SCLK_PORT,SCLK_PIN,GPIO_PIN_RESET)//SCL=SCLK
#define LCD_SCLK_Set() HAL_GPIO_WritePin(SCLK_PORT,SCLK_PIN,GPIO_PIN_SET)
#define LCD_MOSI_Clr() HAL_GPIO_WritePin(SDA_PORT,SDA_PIN,GPIO_PIN_RESET)//SDA=MOSI
#define LCD_MOSI_Set() HAL_GPIO_WritePin(SDA_PORT,SDA_PIN,GPIO_PIN_SET)
#define LCD_RES_Clr() HAL_GPIO_WritePin(RES_PORT,RES_PIN,GPIO_PIN_RESET)//RES
#define LCD_RES_Set() HAL_GPIO_WritePin(RES_PORT,RES_PIN,GPIO_PIN_SET)
#define LCD_DC_Clr() HAL_GPIO_WritePin(DC_PORT,DC_PIN,GPIO_PIN_RESET)//DC
#define LCD_DC_Set() HAL_GPIO_WritePin(DC_PORT,DC_PIN,GPIO_PIN_SET)
#define LCD_CS_Clr() HAL_GPIO_WritePin(CS_PORT,CS_PIN,GPIO_PIN_RESET)//CS
#define LCD_CS_Set() HAL_GPIO_WritePin(CS_PORT,CS_PIN,GPIO_PIN_SET)
#define LCD_BLK_Clr() HAL_GPIO_WritePin(BLK_PORT,BLK_PIN,GPIO_PIN_RESET)//BLK
#define LCD_BLK_Set() HAL_GPIO_WritePin(BLK_PORT,BLK_PIN,GPIO_PIN_SET)
void LCD_GPIO_Init(void);//初始化GPIO
void LCD_Writ_Bus(u8 dat);//模拟SPI时序
void LCD_WR_DATA8(u8 dat);//写入一个字节
void LCD_WR_DATA(u16 dat);//写入两个字节
void LCD_WR_REG(u8 dat);//写入一个指令
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2);//设置坐标函数
void LCD_Init(void);//LCD初始化
void LCD_Set_Light(uint8_t dc);
void LCD_Close_Light(void);
void LCD_ST7789_SleepIn(void);
void LCD_ST7789_SleepOut(void);
void LCD_Open_Light(void);
void LCD_SetRotation(uint16_t rotation);
#endif

View File

@@ -1,535 +0,0 @@
#ifndef __LCDFONT_H
#define __LCDFONT_H
const unsigned char ascii_1206[][12]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x04,0x00,0x00},/*"!",1*/
{0x14,0x14,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/
{0x00,0x00,0x0A,0x0A,0x1F,0x0A,0x0A,0x1F,0x0A,0x0A,0x00,0x00},/*"#",3*/
{0x00,0x04,0x0E,0x15,0x05,0x06,0x0C,0x14,0x15,0x0E,0x04,0x00},/*"$",4*/
{0x00,0x00,0x12,0x15,0x0D,0x15,0x2E,0x2C,0x2A,0x12,0x00,0x00},/*"%",5*/
{0x00,0x00,0x04,0x0A,0x0A,0x36,0x15,0x15,0x29,0x16,0x00,0x00},/*"&",6*/
{0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x10,0x08,0x08,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x00},/*"(",8*/
{0x02,0x04,0x04,0x08,0x08,0x08,0x08,0x08,0x04,0x04,0x02,0x00},/*")",9*/
{0x00,0x00,0x00,0x04,0x15,0x0E,0x0E,0x15,0x04,0x00,0x00,0x00},/*"*",10*/
{0x00,0x00,0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00,0x00,0x00},/*"+",11*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01,0x00},/*",",12*/
{0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",13*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00},/*".",14*/
{0x00,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x00},/*"/",15*/
{0x00,0x00,0x0E,0x11,0x11,0x11,0x11,0x11,0x11,0x0E,0x00,0x00},/*"0",16*/
{0x00,0x00,0x04,0x06,0x04,0x04,0x04,0x04,0x04,0x0E,0x00,0x00},/*"1",17*/
{0x00,0x00,0x0E,0x11,0x11,0x08,0x04,0x02,0x01,0x1F,0x00,0x00},/*"2",18*/
{0x00,0x00,0x0E,0x11,0x10,0x0C,0x10,0x10,0x11,0x0E,0x00,0x00},/*"3",19*/
{0x00,0x00,0x08,0x0C,0x0C,0x0A,0x09,0x1F,0x08,0x1C,0x00,0x00},/*"4",20*/
{0x00,0x00,0x1F,0x01,0x01,0x0F,0x11,0x10,0x11,0x0E,0x00,0x00},/*"5",21*/
{0x00,0x00,0x0C,0x12,0x01,0x0D,0x13,0x11,0x11,0x0E,0x00,0x00},/*"6",22*/
{0x00,0x00,0x1E,0x10,0x08,0x08,0x04,0x04,0x04,0x04,0x00,0x00},/*"7",23*/
{0x00,0x00,0x0E,0x11,0x11,0x0E,0x11,0x11,0x11,0x0E,0x00,0x00},/*"8",24*/
{0x00,0x00,0x0E,0x11,0x11,0x19,0x16,0x10,0x09,0x06,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x04,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x04,0x00},/*";",27*/
{0x00,0x00,0x10,0x08,0x04,0x02,0x02,0x04,0x08,0x10,0x00,0x00},/*"<",28*/
{0x00,0x00,0x00,0x00,0x3F,0x00,0x3F,0x00,0x00,0x00,0x00,0x00},/*"=",29*/
{0x00,0x00,0x02,0x04,0x08,0x10,0x10,0x08,0x04,0x02,0x00,0x00},/*">",30*/
{0x00,0x00,0x0E,0x11,0x11,0x08,0x04,0x04,0x00,0x04,0x00,0x00},/*"?",31*/
{0x00,0x00,0x1C,0x22,0x29,0x2D,0x2D,0x1D,0x22,0x1C,0x00,0x00},/*"@",32*/
{0x00,0x00,0x04,0x04,0x0C,0x0A,0x0A,0x1E,0x12,0x33,0x00,0x00},/*"A",33*/
{0x00,0x00,0x0F,0x12,0x12,0x0E,0x12,0x12,0x12,0x0F,0x00,0x00},/*"B",34*/
{0x00,0x00,0x1E,0x11,0x01,0x01,0x01,0x01,0x11,0x0E,0x00,0x00},/*"C",35*/
{0x00,0x00,0x0F,0x12,0x12,0x12,0x12,0x12,0x12,0x0F,0x00,0x00},/*"D",36*/
{0x00,0x00,0x1F,0x12,0x0A,0x0E,0x0A,0x02,0x12,0x1F,0x00,0x00},/*"E",37*/
{0x00,0x00,0x1F,0x12,0x0A,0x0E,0x0A,0x02,0x02,0x07,0x00,0x00},/*"F",38*/
{0x00,0x00,0x1C,0x12,0x01,0x01,0x39,0x11,0x12,0x0C,0x00,0x00},/*"G",39*/
{0x00,0x00,0x33,0x12,0x12,0x1E,0x12,0x12,0x12,0x33,0x00,0x00},/*"H",40*/
{0x00,0x00,0x1F,0x04,0x04,0x04,0x04,0x04,0x04,0x1F,0x00,0x00},/*"I",41*/
{0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x09,0x07},/*"J",42*/
{0x00,0x00,0x37,0x12,0x0A,0x06,0x0A,0x12,0x12,0x37,0x00,0x00},/*"K",43*/
{0x00,0x00,0x07,0x02,0x02,0x02,0x02,0x02,0x22,0x3F,0x00,0x00},/*"L",44*/
{0x00,0x00,0x3B,0x1B,0x1B,0x1B,0x15,0x15,0x15,0x35,0x00,0x00},/*"M",45*/
{0x00,0x00,0x3B,0x12,0x16,0x16,0x1A,0x1A,0x12,0x17,0x00,0x00},/*"N",46*/
{0x00,0x00,0x0E,0x11,0x11,0x11,0x11,0x11,0x11,0x0E,0x00,0x00},/*"O",47*/
{0x00,0x00,0x0F,0x12,0x12,0x0E,0x02,0x02,0x02,0x07,0x00,0x00},/*"P",48*/
{0x00,0x00,0x0E,0x11,0x11,0x11,0x11,0x17,0x19,0x0E,0x18,0x00},/*"Q",49*/
{0x00,0x00,0x0F,0x12,0x12,0x0E,0x0A,0x12,0x12,0x37,0x00,0x00},/*"R",50*/
{0x00,0x00,0x1E,0x11,0x01,0x06,0x08,0x10,0x11,0x0F,0x00,0x00},/*"S",51*/
{0x00,0x00,0x1F,0x15,0x04,0x04,0x04,0x04,0x04,0x0E,0x00,0x00},/*"T",52*/
{0x00,0x00,0x33,0x12,0x12,0x12,0x12,0x12,0x12,0x0C,0x00,0x00},/*"U",53*/
{0x00,0x00,0x33,0x12,0x12,0x0A,0x0A,0x0C,0x04,0x04,0x00,0x00},/*"V",54*/
{0x00,0x00,0x15,0x15,0x15,0x15,0x0E,0x0A,0x0A,0x0A,0x00,0x00},/*"W",55*/
{0x00,0x00,0x1B,0x0A,0x0A,0x04,0x04,0x0A,0x0A,0x1B,0x00,0x00},/*"X",56*/
{0x00,0x00,0x1B,0x0A,0x0A,0x0A,0x04,0x04,0x04,0x0E,0x00,0x00},/*"Y",57*/
{0x00,0x00,0x1F,0x09,0x08,0x04,0x04,0x02,0x12,0x1F,0x00,0x00},/*"Z",58*/
{0x1C,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x1C,0x00},/*"[",59*/
{0x00,0x02,0x02,0x04,0x04,0x04,0x08,0x08,0x08,0x10,0x10,0x00},/*"\",60*/
{0x0E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x0E,0x00},/*"]",61*/
{0x04,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F},/*"_",63*/
{0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x00,0x00,0x00,0x0C,0x12,0x1C,0x12,0x3C,0x00,0x00},/*"a",65*/
{0x00,0x03,0x02,0x02,0x02,0x0E,0x12,0x12,0x12,0x0E,0x00,0x00},/*"b",66*/
{0x00,0x00,0x00,0x00,0x00,0x1C,0x12,0x02,0x12,0x0C,0x00,0x00},/*"c",67*/
{0x00,0x18,0x10,0x10,0x10,0x1C,0x12,0x12,0x12,0x3C,0x00,0x00},/*"d",68*/
{0x00,0x00,0x00,0x00,0x00,0x0C,0x12,0x1E,0x02,0x1C,0x00,0x00},/*"e",69*/
{0x00,0x18,0x24,0x04,0x04,0x1E,0x04,0x04,0x04,0x1E,0x00,0x00},/*"f",70*/
{0x00,0x00,0x00,0x00,0x00,0x3C,0x12,0x0C,0x02,0x1C,0x22,0x1C},/*"g",71*/
{0x00,0x03,0x02,0x02,0x02,0x0E,0x12,0x12,0x12,0x37,0x00,0x00},/*"h",72*/
{0x00,0x04,0x04,0x00,0x00,0x06,0x04,0x04,0x04,0x0E,0x00,0x00},/*"i",73*/
{0x00,0x08,0x08,0x00,0x00,0x0C,0x08,0x08,0x08,0x08,0x08,0x07},/*"j",74*/
{0x00,0x03,0x02,0x02,0x02,0x1A,0x0A,0x06,0x0A,0x13,0x00,0x00},/*"k",75*/
{0x00,0x07,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x1F,0x00,0x00},/*"l",76*/
{0x00,0x00,0x00,0x00,0x00,0x0F,0x15,0x15,0x15,0x15,0x00,0x00},/*"m",77*/
{0x00,0x00,0x00,0x00,0x00,0x0F,0x12,0x12,0x12,0x37,0x00,0x00},/*"n",78*/
{0x00,0x00,0x00,0x00,0x00,0x0C,0x12,0x12,0x12,0x0C,0x00,0x00},/*"o",79*/
{0x00,0x00,0x00,0x00,0x00,0x0F,0x12,0x12,0x12,0x0E,0x02,0x07},/*"p",80*/
{0x00,0x00,0x00,0x00,0x00,0x1C,0x12,0x12,0x12,0x1C,0x10,0x38},/*"q",81*/
{0x00,0x00,0x00,0x00,0x00,0x1B,0x06,0x02,0x02,0x07,0x00,0x00},/*"r",82*/
{0x00,0x00,0x00,0x00,0x00,0x1E,0x02,0x0C,0x10,0x1E,0x00,0x00},/*"s",83*/
{0x00,0x00,0x00,0x04,0x04,0x1E,0x04,0x04,0x04,0x1C,0x00,0x00},/*"t",84*/
{0x00,0x00,0x00,0x00,0x00,0x1B,0x12,0x12,0x12,0x3C,0x00,0x00},/*"u",85*/
{0x00,0x00,0x00,0x00,0x00,0x1B,0x0A,0x0A,0x04,0x04,0x00,0x00},/*"v",86*/
{0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x0E,0x0A,0x0A,0x00,0x00},/*"w",87*/
{0x00,0x00,0x00,0x00,0x00,0x1B,0x0A,0x04,0x0A,0x1B,0x00,0x00},/*"x",88*/
{0x00,0x00,0x00,0x00,0x00,0x33,0x12,0x12,0x0C,0x08,0x04,0x03},/*"y",89*/
{0x00,0x00,0x00,0x00,0x00,0x1E,0x08,0x04,0x04,0x1E,0x00,0x00},/*"z",90*/
{0x18,0x08,0x08,0x08,0x08,0x0C,0x08,0x08,0x08,0x08,0x18,0x00},/*"{",91*/
{0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08},/*"|",92*/
{0x06,0x04,0x04,0x04,0x04,0x08,0x04,0x04,0x04,0x04,0x06,0x00},/*"}",93*/
{0x16,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",94*/
};
const unsigned char ascii_1608[][16]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x18,0x18,0x00,0x00},/*"!",1*/
{0x00,0x48,0x6C,0x24,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/
{0x00,0x00,0x00,0x24,0x24,0x24,0x7F,0x12,0x12,0x12,0x7F,0x12,0x12,0x12,0x00,0x00},/*"#",3*/
{0x00,0x00,0x08,0x1C,0x2A,0x2A,0x0A,0x0C,0x18,0x28,0x28,0x2A,0x2A,0x1C,0x08,0x08},/*"$",4*/
{0x00,0x00,0x00,0x22,0x25,0x15,0x15,0x15,0x2A,0x58,0x54,0x54,0x54,0x22,0x00,0x00},/*"%",5*/
{0x00,0x00,0x00,0x0C,0x12,0x12,0x12,0x0A,0x76,0x25,0x29,0x11,0x91,0x6E,0x00,0x00},/*"&",6*/
{0x00,0x06,0x06,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x00},/*"(",8*/
{0x00,0x02,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x02,0x00},/*")",9*/
{0x00,0x00,0x00,0x00,0x08,0x08,0x6B,0x1C,0x1C,0x6B,0x08,0x08,0x00,0x00,0x00,0x00},/*"*",10*/
{0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x7F,0x08,0x08,0x08,0x08,0x00,0x00,0x00},/*"+",11*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x04,0x03},/*",",12*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",13*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x00},/*".",14*/
{0x00,0x00,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x00},/*"/",15*/
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00},/*"0",16*/
{0x00,0x00,0x00,0x08,0x0E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"1",17*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x20,0x20,0x10,0x08,0x04,0x42,0x7E,0x00,0x00},/*"2",18*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x20,0x18,0x20,0x40,0x40,0x42,0x22,0x1C,0x00,0x00},/*"3",19*/
{0x00,0x00,0x00,0x20,0x30,0x28,0x24,0x24,0x22,0x22,0x7E,0x20,0x20,0x78,0x00,0x00},/*"4",20*/
{0x00,0x00,0x00,0x7E,0x02,0x02,0x02,0x1A,0x26,0x40,0x40,0x42,0x22,0x1C,0x00,0x00},/*"5",21*/
{0x00,0x00,0x00,0x38,0x24,0x02,0x02,0x1A,0x26,0x42,0x42,0x42,0x24,0x18,0x00,0x00},/*"6",22*/
{0x00,0x00,0x00,0x7E,0x22,0x22,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00},/*"7",23*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00},/*"8",24*/
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x64,0x58,0x40,0x40,0x24,0x1C,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x04},/*";",27*/
{0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x40,0x00,0x00},/*"<",28*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},/*"=",29*/
{0x00,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x00},/*">",30*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x46,0x40,0x20,0x10,0x10,0x00,0x18,0x18,0x00,0x00},/*"?",31*/
{0x00,0x00,0x00,0x1C,0x22,0x5A,0x55,0x55,0x55,0x55,0x2D,0x42,0x22,0x1C,0x00,0x00},/*"@",32*/
{0x00,0x00,0x00,0x08,0x08,0x18,0x14,0x14,0x24,0x3C,0x22,0x42,0x42,0xE7,0x00,0x00},/*"A",33*/
{0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x1E,0x22,0x42,0x42,0x42,0x22,0x1F,0x00,0x00},/*"B",34*/
{0x00,0x00,0x00,0x7C,0x42,0x42,0x01,0x01,0x01,0x01,0x01,0x42,0x22,0x1C,0x00,0x00},/*"C",35*/
{0x00,0x00,0x00,0x1F,0x22,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x22,0x1F,0x00,0x00},/*"D",36*/
{0x00,0x00,0x00,0x3F,0x42,0x12,0x12,0x1E,0x12,0x12,0x02,0x42,0x42,0x3F,0x00,0x00},/*"E",37*/
{0x00,0x00,0x00,0x3F,0x42,0x12,0x12,0x1E,0x12,0x12,0x02,0x02,0x02,0x07,0x00,0x00},/*"F",38*/
{0x00,0x00,0x00,0x3C,0x22,0x22,0x01,0x01,0x01,0x71,0x21,0x22,0x22,0x1C,0x00,0x00},/*"G",39*/
{0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0xE7,0x00,0x00},/*"H",40*/
{0x00,0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"I",41*/
{0x00,0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x11,0x0F},/*"J",42*/
{0x00,0x00,0x00,0x77,0x22,0x12,0x0A,0x0E,0x0A,0x12,0x12,0x22,0x22,0x77,0x00,0x00},/*"K",43*/
{0x00,0x00,0x00,0x07,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x42,0x7F,0x00,0x00},/*"L",44*/
{0x00,0x00,0x00,0x77,0x36,0x36,0x36,0x36,0x2A,0x2A,0x2A,0x2A,0x2A,0x6B,0x00,0x00},/*"M",45*/
{0x00,0x00,0x00,0xE3,0x46,0x46,0x4A,0x4A,0x52,0x52,0x52,0x62,0x62,0x47,0x00,0x00},/*"N",46*/
{0x00,0x00,0x00,0x1C,0x22,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x22,0x1C,0x00,0x00},/*"O",47*/
{0x00,0x00,0x00,0x3F,0x42,0x42,0x42,0x42,0x3E,0x02,0x02,0x02,0x02,0x07,0x00,0x00},/*"P",48*/
{0x00,0x00,0x00,0x1C,0x22,0x41,0x41,0x41,0x41,0x41,0x4D,0x53,0x32,0x1C,0x60,0x00},/*"Q",49*/
{0x00,0x00,0x00,0x3F,0x42,0x42,0x42,0x3E,0x12,0x12,0x22,0x22,0x42,0xC7,0x00,0x00},/*"R",50*/
{0x00,0x00,0x00,0x7C,0x42,0x42,0x02,0x04,0x18,0x20,0x40,0x42,0x42,0x3E,0x00,0x00},/*"S",51*/
{0x00,0x00,0x00,0x7F,0x49,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00},/*"T",52*/
{0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00},/*"U",53*/
{0x00,0x00,0x00,0xE7,0x42,0x42,0x22,0x24,0x24,0x14,0x14,0x18,0x08,0x08,0x00,0x00},/*"V",54*/
{0x00,0x00,0x00,0x6B,0x49,0x49,0x49,0x49,0x55,0x55,0x36,0x22,0x22,0x22,0x00,0x00},/*"W",55*/
{0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x18,0x18,0x18,0x24,0x24,0x42,0xE7,0x00,0x00},/*"X",56*/
{0x00,0x00,0x00,0x77,0x22,0x22,0x14,0x14,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00},/*"Y",57*/
{0x00,0x00,0x00,0x7E,0x21,0x20,0x10,0x10,0x08,0x04,0x04,0x42,0x42,0x3F,0x00,0x00},/*"Z",58*/
{0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78,0x00},/*"[",59*/
{0x00,0x00,0x02,0x02,0x04,0x04,0x08,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x40,0x40},/*"\",60*/
{0x00,0x1E,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1E,0x00},/*"]",61*/
{0x00,0x38,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF},/*"_",63*/
{0x00,0x06,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x78,0x44,0x42,0x42,0xFC,0x00,0x00},/*"a",65*/
{0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x1A,0x26,0x42,0x42,0x42,0x26,0x1A,0x00,0x00},/*"b",66*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x02,0x02,0x02,0x44,0x38,0x00,0x00},/*"c",67*/
{0x00,0x00,0x00,0x60,0x40,0x40,0x40,0x78,0x44,0x42,0x42,0x42,0x64,0xD8,0x00,0x00},/*"d",68*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x7E,0x02,0x02,0x42,0x3C,0x00,0x00},/*"e",69*/
{0x00,0x00,0x00,0xF0,0x88,0x08,0x08,0x7E,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"f",70*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x22,0x22,0x1C,0x02,0x3C,0x42,0x42,0x3C},/*"g",71*/
{0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x3A,0x46,0x42,0x42,0x42,0x42,0xE7,0x00,0x00},/*"h",72*/
{0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x0E,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"i",73*/
{0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x1E},/*"j",74*/
{0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x72,0x12,0x0A,0x16,0x12,0x22,0x77,0x00,0x00},/*"k",75*/
{0x00,0x00,0x00,0x0E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"l",76*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x92,0x92,0x92,0x92,0x92,0xB7,0x00,0x00},/*"m",77*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,0x46,0x42,0x42,0x42,0x42,0xE7,0x00,0x00},/*"n",78*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00},/*"o",79*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x26,0x42,0x42,0x42,0x22,0x1E,0x02,0x07},/*"p",80*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x44,0x42,0x42,0x42,0x44,0x78,0x40,0xE0},/*"q",81*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x4C,0x04,0x04,0x04,0x04,0x1F,0x00,0x00},/*"r",82*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x42,0x02,0x3C,0x40,0x42,0x3E,0x00,0x00},/*"s",83*/
{0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x3E,0x08,0x08,0x08,0x08,0x08,0x30,0x00,0x00},/*"t",84*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x42,0x42,0x42,0x42,0x62,0xDC,0x00,0x00},/*"u",85*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x14,0x08,0x08,0x00,0x00},/*"v",86*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEB,0x49,0x49,0x55,0x55,0x22,0x22,0x00,0x00},/*"w",87*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x24,0x18,0x18,0x18,0x24,0x6E,0x00,0x00},/*"x",88*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x14,0x18,0x08,0x08,0x07},/*"y",89*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x22,0x10,0x08,0x08,0x44,0x7E,0x00,0x00},/*"z",90*/
{0x00,0xC0,0x20,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0xC0,0x00},/*"{",91*/
{0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10},/*"|",92*/
{0x00,0x06,0x08,0x08,0x08,0x08,0x08,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x06,0x00},/*"}",93*/
{0x0C,0x32,0xC2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",94*/
};
const unsigned char ascii_2412[][48]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x00,0x00,0x60,0x06,0x60,0x06,0x30,0x03,0x98,0x01,0x88,0x00,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x02,0x10,0x02,0x10,0x02,0x10,0x02,0xFE,0x07,0xFE,0x07,0x08,0x02,0x08,0x01,0x08,0x01,0x08,0x01,0x08,0x01,0xFE,0x07,0xFE,0x07,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"#",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0xF0,0x01,0x58,0x03,0x4C,0x03,0xCC,0x03,0x4C,0x00,0x58,0x00,0x70,0x00,0xE0,0x00,0xC0,0x01,0xC0,0x01,0x40,0x03,0x4C,0x03,0x5C,0x03,0x4C,0x03,0x48,0x01,0xF0,0x00,0x40,0x00,0x40,0x00,0x00,0x00},/*"$",4*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x01,0x0A,0x01,0x91,0x00,0x91,0x00,0x91,0x00,0x51,0x00,0x51,0x00,0x3A,0x00,0xAE,0x03,0xA0,0x02,0x50,0x04,0x50,0x04,0x48,0x04,0x48,0x04,0x48,0x04,0x84,0x02,0x84,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"%",5*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x2C,0x00,0x98,0x07,0x1C,0x01,0x1A,0x01,0x33,0x01,0x33,0x01,0x63,0x01,0xE3,0x00,0xC3,0x08,0xC6,0x09,0x3C,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*"&",6*/
{0x00,0x00,0x00,0x00,0x0C,0x00,0x1C,0x00,0x10,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x80,0x00,0x80,0x00,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x00},/*"(",8*/
{0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x10,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x00,0x00},/*")",9*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xC0,0x00,0x40,0x00,0x46,0x0C,0x4E,0x0F,0xD0,0x01,0xF0,0x01,0x5E,0x0F,0x46,0x0C,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"*",10*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0xFE,0x0F,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"+",11*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1C,0x00,0x10,0x00,0x10,0x00,0x08,0x00,0x04,0x00},/*",",12*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",13*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x06,0x00,0x02,0x00,0x03,0x00,0x01,0x00,0x01,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x60,0x00,0x20,0x00,0x20,0x00,0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,0x06,0x00,0x02,0x00,0x00,0x00},/*"/",15*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x98,0x01,0x0C,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0x0C,0x03,0x98,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"0",16*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x7C,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",17*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x84,0x01,0x02,0x03,0x06,0x03,0x06,0x03,0x00,0x03,0x00,0x01,0x80,0x01,0xC0,0x00,0x60,0x00,0x20,0x00,0x10,0x00,0x08,0x02,0x04,0x02,0x06,0x02,0xFE,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",18*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0xC6,0x00,0x86,0x01,0x86,0x01,0x80,0x01,0x80,0x01,0xC0,0x00,0x70,0x00,0x80,0x01,0x00,0x01,0x00,0x03,0x00,0x03,0x06,0x03,0x06,0x03,0x86,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",19*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x80,0x01,0xC0,0x01,0xA0,0x01,0xA0,0x01,0x90,0x01,0x88,0x01,0x88,0x01,0x84,0x01,0x82,0x01,0xFE,0x0F,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*"4",20*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xF4,0x00,0x8C,0x01,0x04,0x03,0x00,0x03,0x00,0x03,0x06,0x03,0x06,0x03,0x82,0x01,0x84,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",21*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x18,0x03,0x0C,0x03,0x0C,0x00,0x04,0x00,0x06,0x00,0xE6,0x01,0x16,0x03,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x04,0x06,0x0C,0x02,0x18,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"6",22*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x07,0x0C,0x06,0x04,0x02,0x04,0x01,0x00,0x01,0x00,0x01,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"7",23*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x02,0x1C,0x03,0xF0,0x00,0xC8,0x01,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"8",24*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x0C,0x01,0x0C,0x03,0x06,0x02,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x8C,0x06,0x78,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x0C,0x01,0x8C,0x01,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x40,0x00,0x20,0x00,0x20,0x00},/*";",27*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x80,0x00,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00},/*"<",28*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"=",29*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x80,0x00,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*">",30*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x18,0x06,0x04,0x0C,0x04,0x0C,0x0C,0x0C,0x0C,0x0C,0x00,0x07,0x80,0x01,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"?",31*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x18,0x03,0x0C,0x02,0xCC,0x05,0x64,0x05,0x66,0x05,0xA6,0x05,0xB6,0x04,0xB6,0x04,0xB6,0x04,0xB6,0x04,0xB6,0x02,0xE4,0x01,0x0C,0x04,0x0C,0x02,0x18,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"@",32*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x50,0x00,0xD0,0x00,0x90,0x00,0x90,0x00,0x88,0x00,0x88,0x01,0x08,0x01,0xF8,0x01,0x04,0x03,0x04,0x03,0x04,0x02,0x02,0x02,0x02,0x06,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00},/*"A",33*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x8C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x8C,0x01,0xFC,0x00,0x0C,0x03,0x0C,0x02,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x03,0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"B",34*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x18,0x03,0x0C,0x06,0x0C,0x04,0x04,0x04,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x04,0x0C,0x04,0x0C,0x02,0x18,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"C",35*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x8C,0x01,0x0C,0x03,0x0C,0x03,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x03,0x0C,0x03,0x8C,0x01,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"D",36*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x03,0x06,0x03,0x06,0x04,0x06,0x04,0x06,0x00,0x86,0x00,0x86,0x00,0xFE,0x00,0x86,0x00,0x86,0x00,0x86,0x00,0x06,0x00,0x06,0x04,0x06,0x04,0x06,0x02,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"E",37*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x03,0x06,0x03,0x06,0x04,0x06,0x04,0x06,0x00,0x86,0x00,0x86,0x00,0xFE,0x00,0x86,0x00,0x86,0x00,0x86,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"F",38*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x18,0x01,0x0C,0x02,0x0C,0x02,0x04,0x02,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xC6,0x0F,0x06,0x03,0x06,0x03,0x0C,0x03,0x0C,0x03,0x18,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"G",39*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0xFE,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00},/*"H",40*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"I",41*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x07,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC6,0x00,0x66,0x00,0x3C,0x00},/*"J",42*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCF,0x03,0x86,0x01,0xC6,0x00,0x46,0x00,0x26,0x00,0x16,0x00,0x36,0x00,0x2E,0x00,0x6E,0x00,0x46,0x00,0xC6,0x00,0x86,0x00,0x86,0x01,0x06,0x01,0x06,0x03,0x8F,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*"K",43*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x04,0x06,0x04,0x06,0x02,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"L",44*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x86,0x03,0x86,0x03,0x8E,0x03,0x8E,0x03,0x4E,0x03,0x4E,0x03,0x4A,0x03,0x5A,0x03,0x5A,0x03,0x3A,0x03,0x32,0x03,0x32,0x03,0x32,0x03,0x12,0x03,0x87,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*"M",45*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8E,0x0F,0x0C,0x02,0x1C,0x02,0x1C,0x02,0x34,0x02,0x34,0x02,0x64,0x02,0x64,0x02,0x44,0x02,0xC4,0x02,0x84,0x02,0x84,0x03,0x84,0x03,0x04,0x03,0x04,0x03,0x1F,0x02,0x00,0x00,0x00,0x00,0x00,0x00},/*"N",46*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x98,0x01,0x0C,0x03,0x0C,0x02,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x02,0x0C,0x03,0x98,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"O",47*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x06,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x86,0x03,0xFE,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"P",48*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x98,0x01,0x0C,0x03,0x0C,0x02,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x76,0x06,0x4C,0x02,0xCC,0x03,0x98,0x01,0xF0,0x00,0x80,0x07,0x00,0x03,0x00,0x00},/*"Q",49*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x06,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x03,0xFE,0x00,0x46,0x00,0xC6,0x00,0x86,0x00,0x86,0x01,0x06,0x03,0x06,0x03,0x06,0x06,0x0F,0x0E,0x00,0x00,0x00,0x00,0x00,0x00},/*"R",50*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x02,0x0C,0x03,0x06,0x02,0x06,0x02,0x06,0x00,0x0E,0x00,0x3C,0x00,0xF8,0x00,0xE0,0x03,0x80,0x03,0x00,0x07,0x02,0x06,0x02,0x06,0x06,0x06,0x0C,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"S",51*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x62,0x04,0x61,0x08,0x61,0x08,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"T",52*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x07,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02,0x18,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"U",53*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x07,0x06,0x02,0x04,0x01,0x04,0x01,0x0C,0x01,0x0C,0x01,0x88,0x00,0x88,0x00,0x98,0x00,0x98,0x00,0x50,0x00,0x50,0x00,0x70,0x00,0x30,0x00,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"V",54*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF7,0x0E,0x62,0x04,0x42,0x04,0x46,0x04,0x46,0x04,0x64,0x02,0x64,0x02,0xE4,0x02,0xE4,0x02,0x9C,0x02,0x9C,0x01,0x98,0x01,0x98,0x01,0x88,0x01,0x88,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"W",55*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9E,0x07,0x0C,0x01,0x08,0x01,0x18,0x01,0x90,0x00,0xB0,0x00,0x60,0x00,0x20,0x00,0x60,0x00,0x60,0x00,0xD0,0x00,0x90,0x00,0x88,0x01,0x08,0x01,0x04,0x03,0x8E,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*"X",56*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x06,0x04,0x04,0x02,0x0C,0x02,0x08,0x01,0x18,0x01,0xB8,0x00,0xB0,0x00,0x70,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"Y",57*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0x0C,0x02,0x06,0x03,0x02,0x01,0x80,0x01,0x80,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x10,0x00,0x18,0x00,0x08,0x04,0x0C,0x04,0x04,0x02,0xFE,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"Z",58*/
{0x00,0x00,0x00,0x00,0xE0,0x03,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0xE0,0x03,0x00,0x00},/*"[",59*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0xC0,0x00,0x80,0x00,0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x04},/*"\",60*/
{0x00,0x00,0x00,0x00,0x7C,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7C,0x00,0x00,0x00},/*"]",61*/
{0x00,0x00,0x60,0x00,0x90,0x00,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F},/*"_",63*/
{0x00,0x00,0x00,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x0C,0x03,0x0C,0x03,0x00,0x03,0xE0,0x03,0x1C,0x03,0x0E,0x03,0x06,0x03,0x06,0x03,0x8E,0x0B,0x7C,0x0E,0x00,0x00,0x00,0x00,0x00,0x00},/*"a",65*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xCC,0x01,0x3C,0x03,0x1C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x02,0x1C,0x03,0xE4,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"b",66*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x8C,0x01,0x8C,0x01,0x86,0x01,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x02,0x0C,0x02,0x0C,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"c",67*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xC0,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x78,0x03,0x8C,0x03,0x0C,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x04,0x03,0x8C,0x07,0x78,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"d",68*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x18,0x03,0x08,0x02,0x0C,0x06,0x0C,0x06,0xFC,0x07,0x0C,0x00,0x0C,0x00,0x18,0x04,0x18,0x02,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"e",69*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x60,0x06,0x30,0x06,0x30,0x00,0x30,0x00,0xFE,0x01,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"f",70*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0xD8,0x06,0x8C,0x01,0x8C,0x01,0x8C,0x01,0x98,0x01,0xF8,0x00,0x0C,0x00,0xFC,0x00,0xCC,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xF8,0x00},/*"g",71*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xEC,0x01,0x1C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x9E,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*"h",72*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x7C,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"i",73*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0xF0,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xCC,0x00,0x7C,0x00},/*"j",74*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x8C,0x03,0x8C,0x00,0x8C,0x00,0x4C,0x00,0x6C,0x00,0x5C,0x00,0x8C,0x00,0x8C,0x01,0x0C,0x01,0x0C,0x03,0x9E,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*"k",75*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x7C,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"l",76*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x07,0xEE,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00},/*"m",77*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x01,0x1C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x9E,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*"n",78*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x98,0x01,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0x0C,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"o",79*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x01,0x1C,0x03,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x03,0x1C,0x03,0xEC,0x01,0x0C,0x00,0x0C,0x00,0x3E,0x00},/*"p",80*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x02,0x8C,0x03,0x0C,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x04,0x03,0x8C,0x03,0x78,0x03,0x00,0x03,0x00,0x03,0xC0,0x07},/*"q",81*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9F,0x03,0x58,0x06,0x38,0x06,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"r",82*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x1C,0x03,0x0C,0x02,0x0C,0x02,0x38,0x00,0xF0,0x00,0xC0,0x03,0x04,0x03,0x04,0x03,0x8C,0x03,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"s",83*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x20,0x00,0x30,0x00,0x30,0x00,0xFE,0x01,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x02,0x30,0x02,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"t",84*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x02,0x8E,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x9C,0x07,0x78,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"u",85*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x07,0x0C,0x02,0x08,0x01,0x08,0x01,0x18,0x01,0x90,0x00,0xB0,0x00,0xB0,0x00,0x60,0x00,0x60,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"v",86*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF7,0x0E,0x62,0x04,0x46,0x04,0x64,0x02,0x64,0x02,0xEC,0x02,0x9C,0x01,0x98,0x01,0x98,0x01,0x98,0x01,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"w",87*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBC,0x07,0x18,0x01,0x10,0x01,0xB0,0x00,0x60,0x00,0x60,0x00,0xE0,0x00,0x90,0x00,0x08,0x01,0x08,0x03,0x9E,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*"x",88*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9E,0x07,0x08,0x01,0x08,0x01,0x08,0x01,0x90,0x00,0x90,0x00,0xB0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x1C,0x00},/*"y",89*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x84,0x01,0xC4,0x00,0x44,0x00,0x60,0x00,0x20,0x00,0x30,0x00,0x18,0x02,0x08,0x02,0x0C,0x03,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"z",90*/
{0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x40,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x03,0x00,0x00},/*"{",91*/
{0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00},/*"|",92*/
{0x00,0x00,0x00,0x00,0x0C,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x0C,0x00,0x00,0x00},/*"}",93*/
{0x00,0x00,0x1C,0x00,0x22,0x04,0xC2,0x04,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",94*/
};
const unsigned char ascii_3216[][64]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0xC0,0x03,0xC0,0x03,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x1C,0xE0,0x1C,0xF0,0x1E,0x70,0x0E,0x38,0x07,0x18,0x03,0x08,0x01,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0xFE,0x7F,0xFE,0x7F,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0xFE,0x7F,0xFE,0x7F,0x08,0x04,0x08,0x04,0x08,0x04,0x08,0x04,0x08,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"#",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xC0,0x07,0x60,0x19,0x10,0x31,0x18,0x31,0x18,0x39,0x18,0x39,0x38,0x01,0x70,0x01,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0F,0x00,0x1D,0x00,0x39,0x00,0x31,0x1C,0x31,0x1C,0x31,0x0C,0x31,0x0C,0x11,0x18,0x0D,0xE0,0x07,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00},/*"$",4*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x10,0x36,0x18,0x63,0x08,0x63,0x0C,0x63,0x04,0x63,0x04,0x63,0x02,0x63,0x02,0x63,0x01,0x36,0x1D,0x9C,0x37,0x80,0x22,0x80,0x63,0x40,0x63,0x40,0x63,0x20,0x63,0x20,0x63,0x30,0x63,0x10,0x22,0x18,0x36,0x08,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"%",5*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x98,0x01,0x8C,0x01,0x8C,0x01,0x8C,0x01,0x8C,0x01,0x8C,0x00,0xCC,0x00,0x78,0x00,0x18,0x3E,0x1C,0x08,0x36,0x08,0x32,0x08,0x63,0x04,0x63,0x04,0xC3,0x04,0xC3,0x03,0x83,0x43,0x06,0x43,0x8E,0x26,0x78,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"&",6*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x3C,0x00,0x3C,0x00,0x30,0x00,0x30,0x00,0x10,0x00,0x0C,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x03,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x00},/*"(",8*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x30,0x00,0x20,0x00,0x60,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x00,0x00},/*")",9*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x80,0x03,0x00,0x01,0x1C,0x71,0x3C,0x79,0x78,0x3D,0xC0,0x07,0x00,0x01,0xC0,0x07,0x78,0x3D,0x3C,0x79,0x1C,0x71,0x00,0x01,0x80,0x03,0x80,0x03,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"*",10*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0xFC,0x7F,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"+",11*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x3C,0x00,0x3C,0x00,0x30,0x00,0x30,0x00,0x10,0x00,0x0C,0x00,0x06,0x00},/*",",12*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",13*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x3C,0x00,0x3C,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x60,0x00,0x20,0x00,0x30,0x00,0x10,0x00,0x18,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,0x06,0x00,0x02,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x00,0xC0,0x00,0x40,0x00,0x60,0x00,0x20,0x00,0x30,0x00,0x10,0x00,0x18,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,0x06,0x00,0x02,0x00,0x00,0x00,0x00,0x00},/*"/",15*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x60,0x0C,0x30,0x18,0x18,0x30,0x18,0x30,0x18,0x20,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x18,0x20,0x18,0x30,0x18,0x30,0x30,0x18,0x60,0x0C,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"0",16*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0xF8,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xC0,0x03,0xF8,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",17*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x10,0x1C,0x08,0x18,0x04,0x30,0x04,0x30,0x0C,0x30,0x0C,0x30,0x00,0x30,0x00,0x18,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x00,0x40,0x00,0x20,0x20,0x10,0x20,0x08,0x20,0x04,0x30,0xFC,0x1F,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",18*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x18,0x0E,0x0C,0x0C,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x00,0x18,0x00,0x0C,0x00,0x06,0xC0,0x03,0x00,0x0E,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x10,0x0C,0x18,0x18,0x0C,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",19*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0E,0x00,0x0E,0x00,0x0F,0x80,0x0E,0x80,0x0E,0x40,0x0E,0x60,0x0E,0x20,0x0E,0x10,0x0E,0x10,0x0E,0x08,0x0E,0x04,0x0E,0x04,0x0E,0xFE,0x7F,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"4",20*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x3F,0xF0,0x3F,0x10,0x00,0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0xC8,0x07,0x28,0x0C,0x18,0x18,0x08,0x10,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x0C,0x30,0x0C,0x30,0x04,0x18,0x04,0x18,0x08,0x0C,0xF0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",21*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0xC0,0x10,0x20,0x30,0x10,0x30,0x18,0x00,0x18,0x00,0x08,0x00,0x0C,0x00,0x8C,0x0F,0x6C,0x18,0x3C,0x30,0x1C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x18,0x60,0x18,0x20,0x30,0x30,0x60,0x18,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"6",22*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0xF8,0x3F,0x1C,0x10,0x0C,0x08,0x04,0x08,0x04,0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x80,0x00,0x80,0x00,0x80,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"7",23*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x30,0x0C,0x18,0x18,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x1C,0x30,0x38,0x18,0x70,0x08,0xE0,0x07,0xB0,0x07,0x18,0x0E,0x0C,0x1C,0x06,0x38,0x06,0x30,0x06,0x30,0x06,0x30,0x06,0x30,0x0C,0x18,0x18,0x0C,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"8",24*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x18,0x04,0x0C,0x08,0x0C,0x18,0x06,0x10,0x06,0x30,0x06,0x30,0x06,0x30,0x06,0x30,0x06,0x38,0x0C,0x3C,0x18,0x36,0xF0,0x31,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x18,0x0C,0x0C,0x0C,0x06,0x0C,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0xC0,0x03,0xC0,0x03,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0xC0,0x03,0xC0,0x03,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0xC0,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x00,0x00},/*";",27*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0xC0,0x00,0x80,0x01,0x00,0x03,0x00,0x06,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"<",28*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"=",29*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x60,0x00,0xC0,0x00,0x80,0x01,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0x60,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*">",30*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x30,0x18,0x08,0x30,0x08,0x60,0x0C,0x60,0x1C,0x60,0x1C,0x60,0x1C,0x60,0x00,0x30,0x00,0x1C,0x00,0x06,0x00,0x01,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0xC0,0x03,0xC0,0x03,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"?",31*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x60,0x18,0x10,0x30,0x18,0x20,0x0C,0x2F,0x8C,0x4D,0x86,0x4C,0xC6,0x4C,0xC6,0x4C,0x66,0x4C,0x66,0x44,0x66,0x44,0x66,0x26,0x66,0x26,0x66,0x15,0xCC,0x1C,0x0C,0x40,0x08,0x20,0x18,0x30,0x30,0x18,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"@",32*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x40,0x01,0x60,0x03,0x20,0x03,0x20,0x03,0x20,0x03,0x30,0x06,0x10,0x06,0x10,0x06,0x10,0x06,0xF8,0x0F,0x08,0x0C,0x08,0x0C,0x08,0x0C,0x0C,0x0C,0x04,0x18,0x04,0x18,0x06,0x18,0x1F,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"A",33*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x18,0x1C,0x18,0x38,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x18,0x18,0x0C,0xF8,0x07,0x18,0x18,0x18,0x30,0x18,0x20,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x30,0x18,0x18,0xFE,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"B",34*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x27,0x60,0x38,0x10,0x30,0x18,0x20,0x0C,0x40,0x0C,0x40,0x04,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x0C,0x40,0x0C,0x40,0x0C,0x20,0x18,0x30,0x30,0x18,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"C",35*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x03,0x18,0x0E,0x18,0x18,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x30,0x18,0x30,0x18,0x10,0x18,0x18,0x18,0x0E,0xFE,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"D",36*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x3F,0x18,0x30,0x18,0x20,0x18,0x60,0x18,0x40,0x18,0x00,0x18,0x08,0x18,0x08,0x18,0x0C,0xF8,0x0F,0x18,0x0C,0x18,0x08,0x18,0x08,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x40,0x18,0x40,0x18,0x20,0x18,0x30,0xFE,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"E",37*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0x18,0x70,0x18,0x40,0x18,0xC0,0x18,0x80,0x18,0x00,0x18,0x10,0x18,0x10,0x18,0x18,0xF8,0x1F,0x18,0x18,0x18,0x10,0x18,0x10,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"F",38*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x13,0x70,0x1C,0x10,0x10,0x18,0x10,0x0C,0x20,0x0C,0x20,0x04,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0xFC,0x06,0x30,0x06,0x30,0x0C,0x30,0x0C,0x30,0x18,0x30,0x18,0x30,0x30,0x08,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"G",39*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x7E,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0xFC,0x1F,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x3F,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"H",40*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x1F,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xF8,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"I",41*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x7F,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x0E,0x06,0x0E,0x03,0x8E,0x01,0xFC,0x00},/*"J",42*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x7C,0x18,0x18,0x18,0x08,0x18,0x04,0x18,0x06,0x18,0x02,0x18,0x01,0x98,0x01,0x98,0x01,0xD8,0x01,0xB8,0x03,0x38,0x03,0x18,0x07,0x18,0x06,0x18,0x0E,0x18,0x0C,0x18,0x1C,0x18,0x18,0x18,0x30,0x18,0x30,0x7E,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"K",43*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x40,0x18,0x40,0x18,0x20,0x18,0x30,0xFE,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"L",44*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xF8,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x36,0x74,0x32,0x64,0x32,0x64,0x32,0x64,0x32,0x64,0x31,0xC4,0x31,0xC4,0x31,0xC4,0x31,0xC4,0x30,0xC4,0x30,0x84,0x30,0x9F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"M",45*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x7C,0x1C,0x10,0x3C,0x10,0x34,0x10,0x34,0x10,0x74,0x10,0x64,0x10,0xE4,0x10,0xC4,0x10,0xC4,0x11,0x84,0x11,0x84,0x13,0x04,0x13,0x04,0x17,0x04,0x16,0x04,0x1E,0x04,0x1C,0x04,0x1C,0x04,0x1C,0x04,0x18,0x1F,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"N",46*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x30,0x0C,0x18,0x18,0x08,0x10,0x0C,0x30,0x0C,0x30,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x0C,0x20,0x0C,0x30,0x08,0x10,0x18,0x18,0x30,0x0C,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"O",47*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x18,0x18,0x18,0x30,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x30,0x18,0x18,0xF8,0x0F,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"P",48*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x30,0x0C,0x18,0x18,0x0C,0x10,0x0C,0x30,0x0C,0x20,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0xE4,0x61,0x2C,0x33,0x1C,0x32,0x18,0x16,0x30,0x0E,0xC0,0x07,0x00,0x4C,0x00,0x7C,0x00,0x38,0x00,0x00,0x00,0x00},/*"Q",49*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x18,0x1C,0x18,0x38,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x18,0x18,0x0C,0xF8,0x07,0x98,0x03,0x18,0x03,0x18,0x07,0x18,0x06,0x18,0x06,0x18,0x0E,0x18,0x0C,0x18,0x0C,0x18,0x1C,0x18,0x18,0x7E,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"R",50*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x27,0x30,0x38,0x18,0x30,0x0C,0x20,0x0C,0x20,0x0C,0x00,0x0C,0x00,0x18,0x00,0x78,0x00,0xE0,0x03,0x80,0x0F,0x00,0x1E,0x00,0x38,0x00,0x70,0x00,0x60,0x04,0x60,0x04,0x60,0x08,0x60,0x18,0x30,0x38,0x18,0xC8,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"S",51*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x3F,0x8C,0x21,0x84,0x61,0x82,0x41,0x82,0x41,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"T",52*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x7C,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x0C,0x10,0x08,0x08,0x38,0x04,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"U",53*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0xF8,0x18,0x20,0x18,0x20,0x18,0x20,0x30,0x10,0x30,0x10,0x30,0x10,0x30,0x10,0x60,0x08,0x60,0x08,0x60,0x08,0xE0,0x0C,0xC0,0x04,0xC0,0x04,0xC0,0x04,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"V",54*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDF,0xF3,0x86,0x61,0x86,0x21,0x86,0x21,0x8C,0x21,0x0C,0x21,0x8C,0x23,0x8C,0x13,0x8C,0x13,0x8C,0x13,0x4C,0x13,0x58,0x12,0x58,0x16,0x58,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x30,0x0C,0x10,0x04,0x10,0x04,0x10,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"W",55*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x3E,0x18,0x08,0x38,0x08,0x30,0x04,0x30,0x04,0x70,0x02,0x60,0x02,0xE0,0x01,0xC0,0x01,0xC0,0x01,0x80,0x01,0x80,0x03,0x40,0x03,0x40,0x07,0x20,0x06,0x20,0x06,0x10,0x0C,0x10,0x0C,0x08,0x18,0x08,0x18,0x3E,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"X",56*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x7C,0x1C,0x10,0x18,0x10,0x18,0x08,0x30,0x08,0x30,0x0C,0x70,0x04,0x60,0x04,0x60,0x02,0xC0,0x02,0xC0,0x02,0xC0,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"Y",57*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0x18,0x18,0x08,0x18,0x04,0x0C,0x04,0x0E,0x00,0x06,0x00,0x07,0x00,0x03,0x80,0x03,0x80,0x01,0xC0,0x01,0xC0,0x00,0xE0,0x00,0x60,0x00,0x70,0x00,0x30,0x00,0x38,0x20,0x18,0x20,0x1C,0x10,0x0C,0x18,0xFE,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"Z",58*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00},/*"[",59*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x18,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x20,0x00,0x60,0x00,0x60,0x00,0x40,0x00,0xC0,0x00,0x80,0x00,0x80,0x01,0x80,0x01,0x00,0x01,0x00,0x03,0x00,0x02,0x00,0x06,0x00,0x06,0x00,0x04,0x00,0x0C,0x00,0x08,0x00,0x18,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x20,0x00,0x00},/*"\",60*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0xFC,0x03,0x00,0x00,0x00,0x00},/*"]",61*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x07,0xC0,0x06,0x20,0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF},/*"_",63*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0xC0,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x18,0x06,0x0C,0x0C,0x0C,0x0C,0x00,0x0C,0x80,0x0F,0x70,0x0C,0x1C,0x0C,0x0C,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x4C,0x0C,0x4F,0xF8,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"a",65*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x1E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x0F,0xD8,0x18,0x38,0x30,0x38,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x20,0x38,0x30,0x78,0x18,0xC8,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"b",66*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x70,0x0C,0x18,0x18,0x18,0x18,0x0C,0x18,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x20,0x18,0x20,0x18,0x10,0x30,0x08,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"c",67*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x1E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0xE0,0x1B,0x30,0x1C,0x18,0x18,0x18,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x08,0x18,0x18,0x1C,0x30,0x7A,0xE0,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"d",68*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x30,0x0C,0x18,0x18,0x08,0x10,0x0C,0x30,0x0C,0x30,0xFC,0x3F,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x20,0x18,0x10,0x70,0x18,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"e",69*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x80,0xC3,0x80,0xC0,0xC0,0xC0,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xFC,0x1F,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xF8,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"f",70*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x77,0x30,0x6C,0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x10,0x18,0x30,0x0C,0xF0,0x07,0x18,0x00,0x18,0x00,0xF0,0x0F,0xF0,0x3F,0x08,0x70,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x38,0x38,0xE0,0x0F},/*"g",71*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x1E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x98,0x0F,0xD8,0x18,0x38,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x7E,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"h",72*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xF8,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xF8,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"i",73*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x80,0x1F,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x18,0x0C,0x18,0x06,0xF0,0x03},/*"j",74*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x1E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x3E,0x18,0x0C,0x18,0x06,0x18,0x03,0x18,0x01,0x98,0x01,0xD8,0x01,0x38,0x03,0x18,0x07,0x18,0x06,0x18,0x0C,0x18,0x1C,0x18,0x18,0x7E,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"k",75*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xF8,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xF8,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"l",76*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0xEE,0x1C,0x9C,0x33,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0xDE,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"m",77*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x1E,0x0F,0xD8,0x18,0x38,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x7E,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"n",78*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x70,0x1C,0x10,0x30,0x18,0x30,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,0x18,0x30,0x18,0x30,0x30,0x18,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"o",79*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x9E,0x0F,0x58,0x18,0x38,0x30,0x18,0x20,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x30,0x38,0x30,0x78,0x18,0x98,0x07,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x7E,0x00},/*"p",80*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x23,0x30,0x3C,0x18,0x38,0x18,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x08,0x30,0x18,0x38,0x30,0x3C,0xE0,0x33,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0xFC},/*"q",81*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x7E,0x3C,0x60,0x66,0x60,0x61,0xE0,0x00,0xE0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"r",82*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x27,0x30,0x38,0x18,0x30,0x18,0x20,0x18,0x00,0x70,0x00,0xE0,0x03,0x80,0x0F,0x00,0x1C,0x04,0x30,0x04,0x30,0x0C,0x30,0x1C,0x18,0xEC,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"s",83*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xC0,0x00,0xE0,0x00,0xFC,0x1F,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x20,0xC0,0x20,0x80,0x11,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"t",84*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20,0x1E,0x3C,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x38,0x30,0xF4,0xE0,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"u",85*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x3C,0x18,0x18,0x18,0x08,0x38,0x08,0x30,0x04,0x30,0x04,0x70,0x02,0x60,0x02,0x60,0x02,0xE0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"v",86*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDF,0xF7,0x8E,0x63,0x0C,0x23,0x8C,0x23,0x8C,0x23,0x98,0x13,0x98,0x13,0x58,0x16,0x58,0x16,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x20,0x04,0x20,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"w",87*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x3E,0x70,0x08,0x70,0x04,0xE0,0x04,0xC0,0x02,0xC0,0x01,0x80,0x03,0x80,0x03,0x40,0x07,0x60,0x06,0x20,0x0C,0x10,0x0C,0x18,0x18,0x3E,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"x",88*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x7C,0x18,0x18,0x18,0x08,0x30,0x08,0x30,0x08,0x30,0x04,0x60,0x04,0x60,0x04,0xC0,0x02,0xC0,0x02,0xC0,0x02,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x80,0x00,0x80,0x00,0x4C,0x00,0x3C,0x00},/*"y",89*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x1F,0x0C,0x0C,0x04,0x0E,0x04,0x06,0x00,0x03,0x80,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x20,0x30,0x20,0x38,0x30,0x1C,0x18,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"z",90*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x30,0x00,0x00},/*"{",91*/
{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01},/*"|",92*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x10,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x40,0x00,0x80,0x01,0x40,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x10,0x00,0x0C,0x00,0x00,0x00},/*"}",93*/
{0x00,0x00,0x38,0x00,0xC4,0x00,0x86,0x40,0x02,0x61,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",94*/
};
typedef struct
{
unsigned char Index[2];
unsigned char Msk[24];
}typFNT_GB12;
const typFNT_GB12 tfont12[]={
"",0x20,0x00,0x20,0x00,0x20,0x00,0xFE,0x03,0x22,0x02,0x22,0x02,0x22,0x02,0xFE,0x03,
0x22,0x02,0x20,0x00,0x20,0x00,0x20,0x00,/*"中",0*/
"",0xFC,0x01,0x04,0x01,0xFC,0x01,0x04,0x01,0xFC,0x01,0x20,0x00,0xFF,0x07,0x04,0x01,
0xFC,0x01,0x20,0x00,0x24,0x01,0x32,0x02,/*"景",1*/
"",0xFE,0x07,0x02,0x04,0xFA,0x04,0x02,0x04,0x02,0x04,0xFE,0x05,0x52,0x04,0x52,0x04,
0x4A,0x05,0x86,0x05,0x02,0x04,0xFE,0x07,/*"园",2*/
"",0x10,0x00,0x10,0x00,0xFF,0x01,0x11,0x01,0x11,0x01,0xFF,0x01,0x11,0x01,0x11,0x01,
0xFF,0x01,0x11,0x04,0x10,0x04,0xE0,0x07,/*"电",3*/
"",0x00,0x00,0xFC,0x01,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0xFF,0x07,0x20,0x00,
0x20,0x00,0x20,0x00,0x20,0x00,0x38,0x00,/*"子",4*/
};
typedef struct
{
unsigned char Index[2];
unsigned char Msk[32];
}typFNT_GB16;
const typFNT_GB16 tfont16[]={
"",0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFC,0x1F,0x84,0x10,0x84,0x10,0x84,0x10,
0x84,0x10,0x84,0x10,0xFC,0x1F,0x84,0x10,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,/*"中",0*/
"",0xF8,0x0F,0x08,0x08,0xF8,0x0F,0x08,0x08,0xF8,0x0F,0x80,0x00,0xFF,0x7F,0x00,0x00,
0xF8,0x0F,0x08,0x08,0x08,0x08,0xF8,0x0F,0x80,0x00,0x84,0x10,0xA2,0x20,0x40,0x00,/*"景",1*/
"",0x00,0x00,0xFE,0x3F,0x02,0x20,0xF2,0x27,0x02,0x20,0x02,0x20,0xFA,0x2F,0x22,0x21,
0x22,0x21,0x22,0x21,0x12,0x29,0x12,0x29,0x0A,0x2E,0x02,0x20,0xFE,0x3F,0x02,0x20,/*"园",2*/
"",0x80,0x00,0x80,0x00,0x80,0x00,0xFC,0x1F,0x84,0x10,0x84,0x10,0x84,0x10,0xFC,0x1F,
0x84,0x10,0x84,0x10,0x84,0x10,0xFC,0x1F,0x84,0x50,0x80,0x40,0x80,0x40,0x00,0x7F,/*"电",3*/
"",0x00,0x00,0xFE,0x1F,0x00,0x08,0x00,0x04,0x00,0x02,0x80,0x01,0x80,0x00,0xFF,0x7F,
0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xA0,0x00,0x40,0x00,/*"子",4*/
};
typedef struct
{
unsigned char Index[2];
unsigned char Msk[72];
}typFNT_GB24;
const typFNT_GB24 tfont24[]={
"",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,
0x08,0x00,0x08,0x08,0x18,0xF8,0xFF,0x1F,0x18,0x08,0x18,0x18,0x08,0x18,0x18,0x08,
0x18,0x18,0x08,0x18,0x18,0x08,0x18,0x18,0x08,0x18,0xF8,0xFF,0x1F,0x08,0x08,0x08,
0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x18,0x00,0x00,
0x18,0x00,0x00,0x18,0x00,0x00,0x00,0x00,/*"中",0*/
"",0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x06,0xC0,0xFF,0x07,0x40,0x00,0x06,0xC0,
0xFF,0x07,0x40,0x00,0x06,0xC0,0xFF,0x07,0x40,0x08,0x02,0x00,0x30,0x00,0xFE,0xFF,
0x3F,0x00,0x00,0x00,0xC0,0xFF,0x07,0xC0,0x00,0x02,0xC0,0x00,0x02,0xC0,0x00,0x02,
0xC0,0xFF,0x03,0x80,0x10,0x00,0x80,0x11,0x01,0x60,0x10,0x0E,0x30,0x10,0x18,0x0C,
0x1E,0x30,0x00,0x1C,0x00,0x00,0x00,0x00,/*"景",1*/
"",0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x30,0xF8,0xFF,0x1F,0x08,0x00,0x10,0x08,
0xC0,0x10,0x08,0x3F,0x10,0x08,0x00,0x10,0x08,0x00,0x10,0x08,0x00,0x13,0xC8,0xFF,
0x10,0x08,0x22,0x10,0x08,0x22,0x10,0x08,0x22,0x10,0x08,0x22,0x10,0x08,0x21,0x12,
0x08,0x21,0x14,0x88,0x60,0x16,0x48,0xC0,0x13,0x28,0x00,0x10,0x08,0x00,0x10,0xF8,
0xFF,0x1F,0x08,0x00,0x10,0x00,0x00,0x00,/*"园",2*/
"",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,
0x08,0x00,0xF0,0xFF,0x0F,0x10,0x08,0x04,0x10,0x08,0x04,0x10,0x08,0x04,0x10,0x08,
0x04,0xF0,0xFF,0x07,0x10,0x08,0x04,0x10,0x08,0x04,0x10,0x08,0x04,0x10,0x08,0x04,
0xF0,0xFF,0x07,0x10,0x08,0x00,0x00,0x08,0x10,0x00,0x08,0x10,0x00,0x08,0x20,0x00,
0x18,0x30,0x00,0xF0,0x1F,0x00,0x00,0x00,/*"电",3*/
"",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xF0,0xFF,0x0F,0x00,0x00,0x06,0x00,
0x00,0x01,0x00,0xC0,0x00,0x00,0x28,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,
0x30,0xFE,0xFF,0x7F,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,
0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,
0x1F,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,/*"子",4*/
};
typedef struct
{
unsigned char Index[2];
unsigned char Msk[128];
}typFNT_GB32;
const typFNT_GB32 tfont32[]={
"",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x01,0x00,
0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,
0x10,0x80,0x01,0x0C,0xF0,0xFF,0xFF,0x0F,0x30,0x80,0x01,0x04,0x30,0x80,0x01,0x04,
0x30,0x80,0x01,0x04,0x30,0x80,0x01,0x04,0x30,0x80,0x01,0x04,0x30,0x80,0x01,0x04,
0x30,0x80,0x01,0x04,0x30,0x80,0x01,0x04,0xF0,0xFF,0xFF,0x07,0x30,0x80,0x01,0x04,
0x30,0x80,0x01,0x04,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,
0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,
0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,/*"中",0*/
"",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,
0x00,0xFF,0xFF,0x01,0x00,0x03,0x80,0x01,0x00,0x03,0x80,0x01,0x00,0xFF,0xFF,0x01,
0x00,0x03,0x80,0x01,0x00,0x03,0x80,0x01,0x00,0xFF,0xFF,0x01,0x00,0x81,0x81,0x00,
0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x1C,0xFC,0xFF,0xFF,0x3F,0x00,0x00,0x40,0x00,
0x00,0x03,0xC0,0x01,0x00,0xFF,0xFF,0x01,0x00,0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,
0x00,0x03,0xC0,0x00,0x00,0xFF,0xFF,0x00,0x00,0x01,0x41,0x00,0x00,0x04,0x01,0x00,
0x00,0x0E,0x71,0x00,0x00,0x07,0x81,0x01,0x80,0x01,0x01,0x07,0x60,0x00,0x01,0x0E,
0x18,0x98,0x01,0x1C,0x04,0xE0,0x01,0x18,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,/*"景",1*/
"",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xF0,0xFF,0xFF,0x1F,
0x30,0x00,0x00,0x0C,0x30,0x00,0x00,0x0C,0x30,0x00,0x10,0x0C,0x30,0xFE,0x3F,0x0C,
0x30,0x04,0x00,0x0C,0x30,0x00,0x00,0x0C,0x30,0x00,0x00,0x0C,0x30,0x00,0x00,0x0C,
0x30,0x00,0xC0,0x0C,0xF0,0xFF,0xFF,0x0D,0x30,0x30,0x06,0x0E,0x30,0x30,0x06,0x0C,
0x30,0x10,0x06,0x0C,0x30,0x10,0x06,0x0C,0x30,0x10,0x06,0x0C,0x30,0x18,0x86,0x0C,
0x30,0x18,0x86,0x0C,0x30,0x08,0x06,0x0D,0x30,0x0C,0x86,0x0D,0x30,0x06,0xEE,0x0F,
0x30,0x02,0xFC,0x0D,0x30,0x01,0x00,0x0C,0xF0,0x00,0x00,0x0C,0x30,0x00,0x00,0x0C,
0xF0,0xFF,0xFF,0x0F,0x30,0x00,0x00,0x0C,0x10,0x00,0x00,0x04,0x00,0x00,0x00,0x00,/*"园",2*/
"",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x01,0x00,
0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,
0xE0,0xFF,0xFF,0x03,0x60,0xC0,0x00,0x03,0x60,0xC0,0x00,0x03,0x60,0xC0,0x00,0x03,
0x60,0xC0,0x00,0x03,0x60,0xC0,0x00,0x03,0x60,0xC0,0x00,0x03,0xE0,0xFF,0xFF,0x03,
0x60,0xC0,0x00,0x03,0x60,0xC0,0x00,0x03,0x60,0xC0,0x00,0x03,0x60,0xC0,0x00,0x03,
0x60,0xC0,0x00,0x03,0xE0,0xFF,0xFF,0x03,0x60,0xC0,0x00,0x01,0x60,0xC0,0x00,0x00,
0x00,0xC0,0x00,0x08,0x00,0xC0,0x00,0x10,0x00,0xC0,0x00,0x10,0x00,0xC0,0x00,0x18,
0x00,0xC0,0x01,0x38,0x00,0x80,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"电",3*/
"",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
0xC0,0xFF,0xFF,0x07,0x00,0x00,0x80,0x07,0x00,0x00,0xC0,0x00,0x00,0x00,0x60,0x00,
0x00,0x00,0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0x80,0x03,0x00,0x00,0x80,0x03,0x00,
0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x08,0x00,0x80,0x01,0x1C,0xFC,0xFF,0xFF,0x3F,
0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,
0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,
0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,
0x00,0xFC,0x01,0x00,0x00,0xE0,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,/*"子",4*/
};
#endif

View File

@@ -1,209 +0,0 @@
#ifndef __PIC_H
#define __PIC_H
const unsigned char gImage_1[3200] = { /* 0X10,0X10,0X00,0X28,0X00,0X28,0X01,0X1B, */
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF7,0XBE,
0XFF,0XFF,0XFF,0XDE,0XC6,0X38,0X8C,0X92,0X6B,0X8E,0X6B,0X6E,0X7C,0X10,0XAD,0X96,
0XE7,0X3C,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF,0X5D,
0X9D,0X15,0X63,0X4F,0X42,0X6C,0X32,0X0A,0X29,0X88,0X19,0X46,0X19,0X25,0X21,0X45,
0X31,0XE8,0X6B,0X8E,0XC6,0X38,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XA5,0X36,0X53,0X10,
0X4B,0X10,0X53,0X51,0X4B,0X0F,0X3A,0X6C,0X31,0XE9,0X21,0X67,0X19,0X25,0X10,0XE4,
0X08,0XA3,0X00,0X62,0X08,0X83,0X52,0XCB,0XD6,0X9A,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XE7,0X3C,0X63,0X70,0X63,0XB3,0X7C,0XB8,
0X63,0XF5,0X43,0X11,0X32,0X4D,0X29,0XEA,0X21,0X88,0X19,0X26,0X19,0X05,0X19,0X05,
0X11,0X04,0X11,0X04,0X10,0XE4,0X00,0X83,0X08,0XA3,0X8C,0X72,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XDE,0XDB,0X3A,0X4B,0X42,0XF0,0X6C,0X35,0X4B,0X54,
0X32,0XB1,0X2A,0X2E,0X21,0XEB,0X21,0XA9,0X19,0X67,0X19,0X05,0X11,0X04,0X11,0X04,
0X11,0X04,0X11,0X04,0X11,0X04,0X19,0X05,0X10,0XE4,0X00,0X42,0X73,0XAF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XEF,0X5D,0X32,0X09,0X32,0X4C,0X4B,0X10,0X32,0X8F,0X2A,0X4F,
0X2A,0X2E,0X19,0XCC,0X19,0X89,0X21,0X89,0X19,0X47,0X19,0X05,0X11,0X04,0X11,0X04,
0X10,0XC4,0X10,0XC4,0X11,0X04,0X11,0X04,0X11,0X04,0X10,0XE4,0X00,0X42,0X84,0X31,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0X52,0XEC,0X19,0X47,0X32,0X4C,0X2A,0X0B,0X21,0XEC,0X21,0XEC,
0X22,0X0C,0X5B,0X91,0X4A,0XEE,0X11,0X06,0X19,0X26,0X19,0X04,0X10,0XE4,0X10,0XE4,
0X29,0XA7,0X21,0X66,0X08,0XA3,0X19,0X05,0X11,0X04,0X11,0X04,0X10,0XE4,0X00,0X82,
0XBD,0XF7,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XA5,0X35,0X08,0X83,0X21,0X88,0X21,0X88,0X21,0X89,0X21,0XAA,0X21,0X8A,
0X42,0X6B,0X8C,0X71,0XFF,0XFF,0X8C,0X72,0X08,0X83,0X11,0X04,0X08,0XC4,0X42,0X29,
0XDE,0XFB,0XEF,0X5D,0X5A,0XEC,0X08,0X83,0X11,0X04,0X11,0X04,0X11,0X04,0X08,0X83,
0X31,0XE8,0XFF,0XDF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XF7,0XBE,0X31,0XC7,0X10,0XC4,0X19,0X25,0X19,0X26,0X19,0X47,0X19,0X47,0X29,0XA8,
0X52,0X8A,0X4A,0X28,0XAD,0X55,0XFF,0XFF,0X31,0XE8,0X08,0XA3,0X19,0X05,0X6B,0X4D,
0X6B,0X4D,0XFF,0XFF,0XEF,0X7D,0X21,0X45,0X10,0XC4,0X11,0X04,0X11,0X04,0X11,0X04,
0X00,0X62,0XAD,0X76,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XB5,0X96,0X00,0X62,0X11,0X04,0X19,0X04,0X11,0X05,0X19,0X05,0X08,0XC4,0X4A,0X8B,
0XB5,0XB6,0XEF,0X5D,0XBD,0XF7,0XFF,0XFF,0X6B,0X8E,0X00,0X62,0X42,0X29,0X5A,0XAA,
0X42,0X08,0XFF,0XFF,0XFF,0XFF,0X52,0XCC,0X08,0X83,0X11,0X04,0X11,0X04,0X11,0X04,
0X08,0XA3,0X52,0XAD,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XE7,0X1C,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0X63,0X4E,0X00,0X62,0X11,0X04,0X11,0X04,0X11,0X04,0X10,0XE4,0X00,0X62,0X63,0X8E,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X73,0XCF,0X00,0X01,0X9C,0XF3,0X63,0X2C,
0XB5,0X96,0XFF,0XFF,0XFF,0XFF,0X5B,0X2D,0X00,0X83,0X11,0X04,0X11,0X04,0X11,0X04,
0X10,0XE4,0X21,0X67,0XEF,0X3D,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XBD,0XF8,0XB5,0XB7,0XEF,0X9E,0X52,0XCB,0X94,0XB3,0XFF,0XFF,0XFF,0XFF,0XFF,0XDF,
0X31,0XE8,0X08,0XA3,0X11,0X04,0X11,0X04,0X11,0X04,0X11,0X04,0X08,0XA3,0X42,0X49,
0XF7,0XFF,0XF7,0XFF,0XFF,0XFF,0XFF,0XFF,0X4A,0X6A,0X00,0X01,0X84,0X72,0XFF,0XFF,
0XFF,0XFF,0XF7,0XFF,0XEF,0XDF,0X3A,0X09,0X08,0XA3,0X11,0X04,0X11,0X04,0X11,0X04,
0X11,0X04,0X11,0X05,0XBE,0X18,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0X7B,0XF0,0X00,0X62,0X31,0XE8,0X31,0XC7,0X00,0X41,0XA5,0X35,0XFF,0XFF,0XEF,0X5D,
0X21,0X46,0X10,0XC4,0X11,0X04,0X11,0X04,0X11,0X04,0X11,0X04,0X10,0XE4,0X08,0XA3,
0X9D,0X76,0XF7,0XFF,0XFF,0XFF,0XAD,0XB7,0X08,0XA3,0X08,0XA3,0X31,0XC7,0XE7,0X9E,
0XF7,0XFF,0XF7,0XFF,0XA5,0X76,0X08,0XA3,0X10,0XE4,0X11,0X04,0X11,0X04,0X11,0X04,
0X11,0X05,0X11,0X05,0XA5,0X35,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XDE,0XDB,0X29,0XA7,0X00,0X83,0X10,0XC4,0X10,0XC4,0X10,0XC4,0XE7,0X1C,0XEF,0X9E,
0X11,0X05,0X10,0XE4,0X11,0X04,0X11,0X04,0X11,0X04,0X11,0X04,0X19,0X04,0X08,0XC4,
0X10,0XE5,0X6B,0XD1,0X6B,0XD1,0X08,0XC5,0X00,0X64,0X08,0XA5,0X00,0X43,0X32,0X2B,
0X9D,0X77,0X84,0XB3,0X19,0X25,0X10,0XC4,0X11,0X04,0X11,0X04,0X11,0X04,0X11,0X04,
0X19,0X25,0X09,0X26,0X9D,0X35,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0X73,0XAF,0X00,0X62,0X19,0X04,0X19,0X05,0X00,0X82,0X5B,0X0D,0X9B,0X8E,
0X10,0X62,0X11,0X05,0X11,0X04,0X11,0X04,0X19,0X04,0X10,0XE4,0X00,0X85,0X11,0X05,
0X39,0XC4,0X5A,0X81,0X7B,0X40,0X9C,0X22,0XAC,0X43,0XA4,0X03,0X9B,0X83,0X72,0X82,
0X49,0X82,0X18,0XC2,0X00,0XA4,0X00,0XC5,0X10,0XE4,0X19,0X04,0X11,0X04,0X19,0X05,
0X19,0X47,0X11,0X67,0X5A,0XEC,0XFF,0XBE,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XDF,0XDE,0XDB,0X10,0XC4,0X10,0XE4,0X11,0X04,0X11,0X05,0X18,0XA4,0XC0,0X01,
0X88,0X83,0X00,0XE4,0X19,0X05,0X19,0X04,0X08,0XC5,0X21,0X44,0X83,0X43,0XD5,0X23,
0XFE,0X42,0XFE,0XE4,0XFF,0X27,0XFF,0X07,0XFE,0XA4,0XFE,0X64,0XFE,0X03,0XFD,0XA3,
0XFC,0XE2,0XEC,0X42,0XB3,0X83,0X62,0X24,0X10,0XE5,0X08,0XC4,0X19,0X04,0X19,0X26,
0X19,0XA8,0X21,0X87,0X90,0X00,0XBC,0XD3,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XDF,0XFF,0XFF,0X7C,0X10,0X00,0X42,0X19,0X05,0X11,0X05,0X28,0X83,0XD0,0X01,
0XF8,0X44,0X48,0XA3,0X00,0XE4,0X08,0XC5,0X5A,0X44,0XED,0X02,0XFD,0XE2,0XFE,0X02,
0XFE,0X66,0XFF,0X74,0XFF,0XB8,0XFF,0X73,0XF6,0XE7,0XF6,0XA6,0XF6,0X45,0XF5,0XA4,
0XFC,0XC3,0XFC,0X62,0XFC,0XC2,0XFC,0XC2,0XCB,0XE3,0X49,0XC4,0X11,0X06,0X19,0X88,
0X01,0X87,0X90,0XA4,0XF8,0X01,0X9A,0XEC,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XF7,0XBE,0X31,0XE8,0X00,0X83,0X09,0X05,0X40,0X82,0XC0,0X01,
0XF8,0X23,0XF0,0X85,0X48,0XA3,0X00,0XA4,0X5A,0X44,0XFD,0X02,0XCC,0X23,0XDC,0XC2,
0XFE,0X04,0XFE,0X28,0XF6,0X48,0XF6,0X46,0XF6,0X24,0XF5,0XE4,0XFD,0X64,0XFC,0XE3,
0XFC,0X62,0XFC,0XC2,0XE4,0X02,0XDC,0X02,0XFC,0XE2,0X7A,0XA4,0X01,0X48,0X01,0X67,
0X78,0XC4,0XF8,0X24,0XF8,0X02,0XB0,0X84,0XE7,0X7D,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XDE,0XDB,0X19,0X25,0X00,0XA3,0X38,0XC4,0XE0,0X02,
0XD8,0X22,0XF8,0X44,0XF8,0XA6,0X78,0XA4,0X00,0X63,0X21,0X43,0X72,0X83,0X39,0X83,
0X9B,0X82,0XF5,0X21,0XFD,0X61,0XFD,0X22,0XFC,0XE2,0XFC,0XA2,0XFC,0X42,0XFC,0X42,
0XFC,0X42,0XAB,0X22,0X41,0X83,0X92,0XC3,0X52,0X04,0X01,0X26,0X19,0X25,0X98,0XA4,
0XF8,0X44,0XF8,0X23,0XF8,0X02,0XD0,0XA4,0XEF,0X9E,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XD6,0X9A,0X29,0X87,0X00,0XA5,0XB8,0X43,
0XF8,0X22,0XE0,0X23,0XF8,0X65,0XF8,0XE8,0XC9,0X07,0X48,0X83,0X00,0X42,0X00,0XA3,
0X00,0X84,0X29,0X63,0X7A,0XA2,0XB3,0X62,0XCB,0XA2,0XD3,0X62,0XBB,0X02,0X8A,0X82,
0X39,0X83,0X00,0XA4,0X00,0XE5,0X00,0XE5,0X08,0XE5,0X60,0XC4,0XD8,0X64,0XF8,0X44,
0XF8,0X24,0XF8,0X23,0XF8,0X02,0X88,0X83,0XC6,0XDB,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XE7,0X3D,0X5B,0X50,0X31,0X08,
0XE8,0X23,0XF8,0X43,0XF0,0X44,0XF8,0X65,0XF9,0X09,0XF9,0XAB,0XD1,0X89,0X89,0X06,
0X48,0XA3,0X18,0X42,0X00,0X02,0X00,0X42,0X00,0X61,0X00,0X82,0X00,0X62,0X00,0X62,
0X00,0X83,0X20,0XA3,0X50,0XC4,0X88,0XA5,0XD8,0X85,0XF8,0X65,0XF8,0X44,0XF8,0X44,
0XF8,0X23,0XF8,0X23,0XD0,0X03,0X10,0X82,0X29,0XC7,0XEF,0X5D,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X32,0X6C,
0X38,0XA5,0XD8,0X02,0XF8,0X23,0XF8,0X65,0XF8,0X66,0XF8,0XA7,0XF9,0X4A,0XFA,0X0C,
0XFA,0X4D,0XEA,0X4C,0XD2,0X0B,0XB9,0XA9,0XB1,0X68,0XA9,0X47,0XB1,0X27,0XB9,0X07,
0XD1,0X07,0XE8,0XE7,0XF8,0XC7,0XF8,0XA7,0XF8,0X65,0XF8,0X65,0XF8,0X44,0XF8,0X23,
0XF8,0X03,0XD0,0X02,0X28,0XA3,0X09,0X05,0X08,0XC4,0X5A,0XEC,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XDE,0XFB,0X19,0X05,
0X00,0XC4,0X41,0XA7,0XC0,0XE6,0XF8,0X03,0XF8,0X86,0XF8,0XA7,0XF8,0X87,0XF8,0X86,
0XF8,0XC7,0XF9,0X29,0XF9,0X8A,0XF9,0XAB,0XF9,0XAB,0XF9,0X8B,0XF9,0X6A,0XF9,0X29,
0XF9,0X08,0XF8,0XC7,0XF8,0XA6,0XF8,0X86,0XF8,0X65,0XF8,0X64,0XF8,0X23,0XF0,0X02,
0XB1,0X06,0X29,0X25,0X00,0XE4,0X10,0XE4,0X19,0X25,0X19,0X25,0X9D,0X14,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XAD,0X96,0X00,0X62,
0X08,0X82,0X95,0X35,0XCE,0XBA,0XA2,0X8B,0XD0,0X44,0XF8,0X25,0XF8,0X87,0XF8,0XA7,
0XF8,0XC7,0XF8,0XA7,0XF8,0X87,0XF8,0X86,0XF8,0X86,0XF8,0X86,0XF8,0X87,0XF8,0XA7,
0XF8,0XA7,0XF8,0XA6,0XF8,0X85,0XF8,0X65,0XF8,0X64,0XF0,0X24,0XB8,0X64,0X93,0X0D,
0XB6,0XBB,0X63,0XCF,0X08,0X83,0X11,0X04,0X10,0XE4,0X21,0X66,0X3A,0X49,0XEF,0X5D,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X94,0XD3,0X00,0X42,
0X10,0XE4,0XCE,0XBB,0XFF,0XFF,0XE7,0XBE,0XB5,0X76,0XAA,0XCC,0XC1,0X07,0XE0,0X45,
0XF8,0X45,0XF8,0X46,0XF8,0X66,0XF8,0X86,0XF8,0X86,0XF8,0X86,0XF8,0X86,0XF8,0X65,
0XF8,0X45,0XF8,0X65,0XE8,0X65,0XD0,0X44,0XA8,0X43,0X88,0X01,0X90,0X82,0XD7,0X3C,
0XEF,0XFF,0X95,0X55,0X08,0X83,0X11,0X04,0X11,0X04,0X19,0X05,0X19,0X46,0X94,0XB3,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X94,0XB3,0X00,0X41,
0X21,0X86,0XDF,0X5D,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XE7,0XDF,0XC6,0X7A,0XB4,0XD3,
0XB3,0X4E,0XC2,0X2A,0XD1,0X68,0XE0,0XE6,0XE8,0XA6,0XE8,0XA5,0XE8,0XA5,0XD8,0XE6,
0XC9,0X88,0XA9,0X06,0XA8,0X22,0XA8,0X02,0XA0,0X00,0XC8,0X00,0XD8,0X00,0XE5,0XF7,
0XE7,0XFF,0XAD,0XF8,0X10,0XC4,0X10,0XE4,0X11,0X04,0X10,0XE4,0X11,0X05,0X4A,0X8B,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XA5,0X55,0X00,0X41,
0X29,0XA7,0XDF,0X5D,0XF7,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XEF,0XFF,0XDF,0X7D,0XCE,0XDB,0XCE,0X59,0XCD,0XF8,0XCD,0XD7,0XC5,0XF7,0XCE,0X79,
0XBE,0XFB,0XA2,0XAB,0XF0,0X03,0XF8,0X45,0XD0,0X42,0XE8,0X43,0XF0,0X00,0XD4,0X72,
0XDF,0XFF,0XAE,0X39,0X10,0XE4,0X10,0XE4,0X11,0X04,0X10,0XE4,0X11,0X05,0X29,0X87,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XCE,0X59,0X08,0X83,
0X21,0X46,0XD7,0X1C,0XF7,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XEF,0XFF,0XBA,0X8B,0XF8,0X04,0XF8,0X45,0XE0,0X62,0XF0,0X44,0XF8,0X00,0XDB,0X8E,
0XDF,0XFF,0XA5,0XF8,0X10,0XC4,0X10,0XE4,0X10,0XE4,0X11,0X04,0X10,0XE4,0X19,0X25,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF7,0XBE,0X29,0X87,
0X08,0X83,0XB6,0X39,0XF7,0XFF,0XF7,0XDF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XE7,0XBE,0XBA,0X4A,0XF8,0X03,0XF8,0X45,0XF8,0X64,0XF8,0X44,0XF8,0X00,0XE3,0X6E,
0XD7,0XFF,0X8C,0XF4,0X08,0X83,0X11,0X04,0X10,0XE4,0X10,0XE4,0X10,0XE4,0X19,0X05,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X73,0XEF,
0X00,0X00,0X84,0X72,0XEF,0XFF,0XEF,0XBE,0XFF,0XDF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XE7,0XDF,0XBA,0X8B,0XF8,0X03,0XF8,0X45,0XF8,0X45,0XF8,0X23,0XF8,0X00,0XD4,0XD3,
0XD7,0XFF,0X5B,0X4E,0X00,0X21,0X3A,0X29,0XA5,0X55,0X08,0X83,0X10,0XC4,0X19,0X25,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XDE,0XFB,
0X08,0XA3,0X31,0XE8,0XDF,0X9E,0XE7,0X9E,0XEF,0XBF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XF7,0XFF,0XBC,0X51,0XE0,0X02,0XF8,0X03,0XF0,0X03,0XE0,0X43,0XC2,0XEC,0XCF,0X7E,
0XBE,0XFC,0X21,0X46,0X00,0X21,0X94,0XD3,0XFF,0XFF,0X84,0X51,0X00,0X00,0X29,0X87,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0X84,0X51,0X00,0X00,0X8C,0XF4,0XEF,0XFF,0XE7,0X9E,0XEF,0XBF,0XFF,0XDF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XDF,0X3D,0XBD,0X55,0XBC,0X52,0XBC,0X72,0XB5,0XB7,0XC7,0X5D,0XDF,0XFF,
0X6B,0XF0,0X00,0X00,0X3A,0X09,0XF7,0XBF,0XFF,0XFF,0XFF,0XFF,0X9D,0X14,0XA5,0X55,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0X4A,0XAC,0X08,0XA4,0XBE,0XBB,0XE7,0XDF,0XE7,0X7E,0XEF,0XBE,0XF7,0XDF,
0XFF,0XDF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XDF,0XF7,0XDF,0XEF,0XFF,0XDF,0XDF,0XD7,0XBF,0XD7,0X9E,0XDF,0XDF,0XA5,0XD8,
0X08,0X83,0X11,0X26,0XD6,0XDB,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XEE,0X79,0XDC,0X8B,0X31,0X21,0X21,0XA9,0XCF,0X3D,0XDF,0XBF,0XDF,0X7E,0XE7,0X9E,
0XEF,0XBE,0XEF,0XBF,0XF7,0XDF,0XF7,0XDF,0XF7,0XDF,0XF7,0XDF,0XF7,0XDF,0XEF,0XBF,
0XEF,0XBE,0XE7,0X9E,0XDF,0X7E,0XD7,0X5E,0XD7,0X5E,0XDF,0XDF,0XB6,0X9A,0X19,0X26,
0X08,0X42,0XA3,0XED,0XFF,0XBF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XDD,0X74,
0XDB,0XC0,0XFE,0X00,0XEE,0X42,0X42,0X02,0X21,0X89,0XB6,0X7B,0XDF,0XDF,0XD7,0X7E,
0XDF,0X7E,0XDF,0X7E,0XE7,0X9E,0XE7,0X9E,0XE7,0X9E,0XE7,0X9E,0XE7,0X9E,0XDF,0X7E,
0XDF,0X7E,0XD7,0X5D,0XD7,0X5D,0XDF,0X9E,0XE7,0XFF,0XA5,0XF8,0X11,0X07,0X18,0XE3,
0XC5,0X02,0XFD,0X60,0XD3,0XE6,0XEE,0XDB,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF7,0X9E,0XBA,0X84,
0XFC,0XC1,0XFE,0X42,0XFE,0X82,0XFE,0XA2,0X83,0X81,0X21,0X45,0X74,0X74,0XC7,0X5E,
0XDF,0XDF,0XD7,0X7E,0XD7,0X5E,0XD7,0X5D,0XD7,0X5E,0XD7,0X5E,0XD7,0X5D,0XD7,0X5D,
0XD7,0X5E,0XDF,0X9E,0XE7,0XFF,0XC7,0X3D,0X63,0XF1,0X08,0X84,0X52,0X42,0XE6,0X26,
0XFF,0X29,0XFE,0X86,0XF3,0XE0,0XC3,0X6A,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XDE,0X18,0XD2,0XC1,
0XFD,0XA2,0XFE,0X22,0XFE,0X42,0XFE,0X42,0XFE,0X62,0XD4,0XE2,0X6A,0X41,0X42,0X49,
0X74,0X53,0XA6,0X3B,0XC7,0X3E,0XD7,0XBF,0XD7,0XBF,0XD7,0XBF,0XDF,0XBF,0XD7,0XBF,
0XC7,0X3E,0XA6,0X1A,0X63,0XF2,0X29,0XA7,0X41,0X82,0XB4,0X22,0XFE,0X62,0XFE,0X83,
0XFE,0XAA,0XFF,0X0F,0XFD,0X67,0XBA,0X63,0XEF,0X3C,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XE6,0X9A,0XD2,0X80,
0XFD,0X21,0XFD,0XC2,0XF5,0XE2,0XF5,0XC2,0XF5,0X82,0XFD,0X82,0XFD,0X62,0XDC,0X61,
0X9B,0X21,0X6A,0X84,0X6A,0XE9,0X63,0X2C,0X63,0XAF,0X74,0X11,0X63,0X6E,0X63,0X2C,
0X5A,0X89,0X52,0X04,0X7A,0X81,0XCB,0XC2,0XFC,0XE2,0XFD,0X62,0XFD,0X82,0XFD,0XC2,
0XFD,0XC2,0XFD,0XE4,0XFD,0X24,0XCA,0X62,0XE7,0X1C,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XCC,0XB1,
0XD2,0X81,0XF3,0XC0,0XFC,0XC1,0XFD,0X02,0XFD,0X02,0XFC,0XE2,0XFC,0XC2,0XFC,0XC2,
0XFC,0X81,0XFB,0X80,0XC9,0XC0,0X81,0XA4,0XAD,0X35,0XCE,0X59,0X9C,0X71,0X81,0X21,
0XDA,0X00,0XFB,0XA1,0XFC,0X82,0XFC,0XA2,0XFC,0X82,0XFC,0XA2,0XFD,0X02,0XFD,0X22,
0XFC,0XE2,0XFC,0X00,0XDA,0X60,0XCC,0X90,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XDE,0X59,0XC4,0X0D,0XCB,0X06,0XD2,0XE4,0XDB,0X03,0XDB,0X03,0XDA,0XE3,0XD2,0XC3,
0XC2,0XA4,0XB3,0X09,0XBC,0XD2,0XF7,0X9E,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XE6,0XFB,
0XB4,0X0E,0XBA,0XA6,0XD2,0X83,0XE2,0XE3,0XEB,0X02,0XEB,0X22,0XE3,0X22,0XDB,0X03,
0XD2,0XE4,0XC3,0X6A,0XD5,0XB6,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
};
#endif

View File

@@ -1,596 +0,0 @@
/**
* FUSB302_UFP.c
*
* Updated on: Jan 4, 2021
* Author: Ryan Ma
*
* Minimalist USB PD implement with only UFP(device) functionality
* Requires only stdint.h and string.h
* No use of bit-field for better cross-platform compatibility
*
* FUSB302 can support PD3.0 with limitations and workarounds
* - Do not have enough FIFO for unchunked message, use chunked message instead
* - VBUS sense low threshold at 4V, disable vbus_sense if request PPS below 4V
*
*/
#include <string.h>
#include "FUSB302_UFP.h"
/* Switches0 : 02h */
#define PU_EN2 (0x01 << 7)
#define PU_EN1 (0x01 << 6)
#define VCONN_CC2 (0x01 << 5)
#define VCONN_CC1 (0x01 << 4)
#define MEAS_CC2 (0x01 << 3)
#define MEAS_CC1 (0x01 << 2)
#define PDWN2 (0x01 << 1)
#define PDWN1 (0x01 << 0)
/* Switches1 : 03h */
#define POWERROLE (0x01 << 7)
#define SPECREV1 (0x01 << 6)
#define SPECREV0 (0x01 << 5)
#define DATAROLE (0x01 << 4)
#define AUTO_CRC (0x01 << 2)
#define TXCC2 (0x01 << 1)
#define TXCC1 (0x01 << 0)
/* Measure : 04h */
#define MEAS_VBUS (0x01 << 6)
/* Control0 : 06h */
#define TX_FLUSH (0x01 << 6)
#define INT_MASK (0x01 << 5)
#define HOST_CUR_MASK (0x03 << 2)
#define HOST_CUR_3A0 (0x03 << 2)
#define HOST_CUR_1A5 (0x02 << 2)
#define HOST_CUR_USB (0x01 << 2)
#define AUTO_PRE (0x01 << 1)
#define TX_START (0x01 << 0)
/* Control1 : 07h */
#define ENSOP2DB (0x01 << 6)
#define ENSOP1DB (0x01 << 5)
#define BIST_MODE2 (0x01 << 4)
#define RX_FLUSH (0x01 << 2)
#define ENSOP2 (0x01 << 1)
#define ENSOP1 (0x01 << 0)
/* Control2 : 08h */
#define WAKE_EN (0x01 << 3)
#define MODE_MASK (0x03 << 1)
#define MODE_DFP (0x03 << 1)
#define MODE_UFP (0x02 << 1)
#define MODE_DRP (0x01 << 1)
#define TOGGLE (0x01 << 0)
/* Control3 : 09h */
#define SEND_HARDRESET (0x01 << 6)
#define BIST_TMODE (0x01 << 5) /* on FUSB302B only */
#define AUTO_HARDRESET (0x01 << 4)
#define AUTO_SOFTRESET (0x01 << 3)
#define N_RETRIES_MASK (0x03 << 1)
#define N_RETRIES(n) ((n) << 1)
#define AUTO_RETRY (0x01 << 0)
/* Mask : 0Ah */
#define M_VBUSOK (0x01 << 7)
#define M_ACTIVITY (0x01 << 6)
#define M_COMP_CHNG (0x01 << 5)
#define M_CRC_CHK (0x01 << 4)
#define M_ALERT (0x01 << 3)
#define M_WAKE (0x01 << 2)
#define M_COLLISION (0x01 << 1)
#define M_BC_LVL (0x01 << 0)
/* Power : 0Bh */
#define PWR_INT_OSC (0x01 << 3) /* Enable internal oscillator */
#define PWR_MEASURE (0x01 << 2) /* Measure block powered */
#define PWR_RECEIVER (0x01 << 1) /* Receiver powered and current reference for Measure block */
#define PWR_BANDGAP (0x01 << 0) /* Bandgap and wake circuitry */
/* Reset : 0Ch */
#define PD_RESET (0x01 << 1)
#define SW_RES (0x01 << 0)
/* Maska : 0Eh */
#define M_OCP_TEMP (0x01 << 7)
#define M_TOGDONE (0x01 << 6)
#define M_SOFTFAIL (0x01 << 5)
#define M_RETRYFAIL (0x01 << 4)
#define M_HARDSENT (0x01 << 3)
#define M_TXSENT (0x01 << 2)
#define M_SOFTRST (0x01 << 1)
#define M_HARDRST (0x01 << 0)
/* Maskb : 0Fh */
#define M_GCRCSENT (0x01 << 0)
/* Status0a : 3Ch */
#define SOFTFAIL (0x01 << 5)
#define RETRYFAIL (0x01 << 4)
#define POWER3_2 (0x01 << 2)
#define SOFTRST (0x01 << 1)
#define HARDRST (0x01 << 0)
/* Status1a : 3Dh */
#define TOGSS_MASK (0x07 << 3)
#define TOGSS_RUNNING (0x00 << 3)
#define TOGSS_SRC1 (0x01 << 3)
#define TOGSS_SRC2 (0x02 << 3)
#define TOGSS_SNK1 (0x05 << 3)
#define TOGSS_SNK2 (0x06 << 3)
#define TOGSS_AUDIOA (0x07 << 3)
#define RXSOP2DB (0x01 << 2)
#define RXSOP1DB (0x01 << 1)
#define RXSOP (0x01 << 0)
/* Interrupta : 3Eh */
#define I_OCP_TEMP (0x01 << 7)
#define I_TOGDONE (0x01 << 6)
#define I_SOFTFAIL (0x01 << 5)
#define I_RETRYFAIL (0x01 << 4)
#define I_HARDSENT (0x01 << 3)
#define I_TXSENT (0x01 << 2)
#define I_SOFTRST (0x01 << 1)
#define I_HARDRST (0x01 << 0)
/* Interruptb : 3Fh */
#define I_GCRCSENT (0x01 << 0)
/* Status0 : 40h */
#define VBUSOK (0x01 << 7)
#define ACTIVITY (0x01 << 6)
#define COMP (0x01 << 5)
#define CRC_CHK (0x01 << 4)
#define ALERT (0x01 << 3)
#define WAKE (0x01 << 2)
#define BC_LVL_MASK (0x03 << 0)
#define BC_LVL_LT200 (0x00 << 0)
#define BC_LVL_200_660 (0x01 << 0)
#define BC_LVL_660_1230 (0x02 << 0)
#define BC_LVL_GT1230 (0x03 << 0)
/* Status1 : 41h */
#define RXSOP2 (0x01 << 7)
#define RXSOP1 (0x01 << 6)
#define RX_EMPTY (0x01 << 5)
#define RX_FULL (0x01 << 4)
#define TX_EMPTY (0x01 << 3)
#define TX_FULL (0x01 << 2)
#define OVRTEMP (0x01 << 1)
#define OCP (0x01 << 0)
/* Interrupt : 42h */
#define I_VBUSOK (0x01 << 7)
#define I_ACTIVITY (0x01 << 6)
#define I_COMP_CHNG (0x01 << 5)
#define I_CRC_CHK (0x01 << 4)
#define I_ALERT (0x01 << 3)
#define I_WAKE (0x01 << 2)
#define I_COLLISION (0x01 << 1)
#define I_BC_LVL (0x01 << 0)
#define ADDRESS_DEVICE_ID 0x01
#define ADDRESS_SWITCHES0 0x02
#define ADDRESS_SWITCHES1 0x03
#define ADDRESS_MEASURE 0x04
#define ADDRESS_SLICE 0x05
#define ADDRESS_CONTROL0 0x06
#define ADDRESS_CONTROL1 0x07
#define ADDRESS_CONTROL2 0x08
#define ADDRESS_CONTROL3 0x09
#define ADDRESS_MASK 0x0A
#define ADDRESS_POWER 0x0B
#define ADDRESS_RESET 0x0C
#define ADDRESS_MASKA 0x0E
#define ADDRESS_MASKB 0x0F
#define ADDRESS_STATUS0A 0x3C
#define ADDRESS_STATUS1A 0x3D
#define ADDRESS_INTERRUPTA 0x3E
#define ADDRESS_INTERRUPTB 0x3F
#define ADDRESS_STATUS0 0x40
#define ADDRESS_STATUS1 0x41
#define ADDRESS_INTERRUPT 0x42
#define ADDRESS_FIFOS 0x43
#define REG_DEVICE_ID dev->reg_control[ADDRESS_DEVICE_ID - ADDRESS_DEVICE_ID]
#define REG_SWITCHES0 dev->reg_control[ADDRESS_SWITCHES0 - ADDRESS_DEVICE_ID]
#define REG_SWITCHES1 dev->reg_control[ADDRESS_SWITCHES1 - ADDRESS_DEVICE_ID]
#define REG_MEASURE dev->reg_control[ADDRESS_MEASURE - ADDRESS_DEVICE_ID]
#define REG_SLICE dev->reg_control[ADDRESS_SLICE - ADDRESS_DEVICE_ID]
#define REG_CONTROL0 dev->reg_control[ADDRESS_CONTROL0 - ADDRESS_DEVICE_ID]
#define REG_CONTROL1 dev->reg_control[ADDRESS_CONTROL1 - ADDRESS_DEVICE_ID]
#define REG_CONTROL2 dev->reg_control[ADDRESS_CONTROL2 - ADDRESS_DEVICE_ID]
#define REG_CONTROL3 dev->reg_control[ADDRESS_CONTROL3 - ADDRESS_DEVICE_ID]
#define REG_MASK dev->reg_control[ADDRESS_MASK - ADDRESS_DEVICE_ID]
#define REG_POWER dev->reg_control[ADDRESS_POWER - ADDRESS_DEVICE_ID]
#define REG_RESET dev->reg_control[ADDRESS_RESET - ADDRESS_DEVICE_ID]
#define REG_MASKA dev->reg_control[ADDRESS_MASKA - ADDRESS_DEVICE_ID]
#define REG_MASKB dev->reg_control[ADDRESS_MASKB - ADDRESS_DEVICE_ID]
#define REG_STATUS0A dev->reg_status[ADDRESS_STATUS0A - ADDRESS_STATUS0A]
#define REG_STATUS1A dev->reg_status[ADDRESS_STATUS1A - ADDRESS_STATUS0A]
#define REG_INTERRUPTA dev->reg_status[ADDRESS_INTERRUPTA - ADDRESS_STATUS0A]
#define REG_INTERRUPTB dev->reg_status[ADDRESS_INTERRUPTB - ADDRESS_STATUS0A]
#define REG_STATUS0 dev->reg_status[ADDRESS_STATUS0 - ADDRESS_STATUS0A]
#define REG_STATUS1 dev->reg_status[ADDRESS_STATUS1 - ADDRESS_STATUS0A]
#define REG_INTERRUPT dev->reg_status[ADDRESS_INTERRUPT - ADDRESS_STATUS0A]
enum FUSB302_transmit_data_tokens_t {
TX_TOKEN_TXON = 0xA1,
TX_TOKEN_SOP1 = 0x12,
TX_TOKEN_SOP2 = 0x13,
TX_TOKEN_SOP3 = 0x1B,
TX_TOKEN_RESET1 = 0x15,
TX_TOKEN_RESET2 = 0x16,
TX_TOKEN_PACKSYM = 0x80,
TX_TOKEN_JAM_CRC = 0xFF,
TX_TOKEN_EOP = 0x14,
TX_TOKEN_TXOFF = 0xFE,
};
enum FUSB302_state_t {
FUSB302_STATE_UNATTACHED = 0,
FUSB302_STATE_ATTACHED
};
#define FUSB302_ERR_MSG(s) s
#define REG_READ(addr, data, count) do { \
if (reg_read(dev, addr, data, count) != FUSB302_SUCCESS) { return FUSB302_ERR_READ_DEVICE; } \
} while(0)
#define REG_WRITE(addr, data, count) do { \
if (reg_write(dev, addr, data, count) != FUSB302_SUCCESS) { return FUSB302_ERR_WRITE_DEVICE; } \
} while(0)
static inline FUSB302_ret_t reg_read(FUSB302_dev_t *dev, uint8_t address, uint8_t *data, uint8_t count)
{
FUSB302_ret_t ret = dev->i2c_read(dev->i2c_address, address, data, count);
if (ret != FUSB302_SUCCESS) {
dev->err_msg = FUSB302_ERR_MSG("Fail to read register");
}
return ret;
}
static inline FUSB302_ret_t reg_write(FUSB302_dev_t *dev, uint8_t address, uint8_t *data, uint8_t count)
{
FUSB302_ret_t ret = dev->i2c_write(dev->i2c_address, address, data, count);
if (ret != FUSB302_SUCCESS) {
dev->err_msg = FUSB302_ERR_MSG("Fail to write register");
}
return ret;
}
static FUSB302_ret_t FUSB302_read_cc_lvl(FUSB302_dev_t *dev, uint8_t * cc_value)
{
/* 00: < 200 mV : vRa
01: >200 mV, <660 mV : vRd-USB
10: >660 mV, <1.23 V : vRd-1.5
11: >1.23 V : vRd-3.0 */
uint8_t cc, cc_verify;
REG_READ(ADDRESS_STATUS0, &REG_STATUS0, 1);
cc = REG_STATUS0 & BC_LVL_MASK;
for (uint8_t i = 0; i < 5; i++) {
REG_READ(ADDRESS_STATUS0, &REG_STATUS0, 1);
cc_verify = REG_STATUS0 & BC_LVL_MASK;
if (cc != cc_verify) {
return FUSB302_BUSY;
}
}
*cc_value = cc;
return FUSB302_SUCCESS;
}
static FUSB302_ret_t FUSB302_read_incoming_packet(FUSB302_dev_t *dev, FUSB302_event_t * events)
{
uint8_t len, b[3];
REG_READ(ADDRESS_FIFOS, b, 3);
dev->rx_header = ((uint16_t)b[2] << 8) | b[1];
len = (dev->rx_header >> 12) & 0x7;
REG_READ(ADDRESS_FIFOS, dev->rx_buffer, len * 4 + 4); /* add 4 to len to read CRC out */
if (events) {
*events |= FUSB302_EVENT_RX_SOP;
}
return FUSB302_SUCCESS;
}
static FUSB302_ret_t FUSB302_state_unattached(FUSB302_dev_t *dev, FUSB302_event_t * events)
{
REG_READ(ADDRESS_STATUS0, &REG_STATUS0, 1);
if (REG_STATUS0 & VBUSOK) {
/* enable internal oscillator */
REG_POWER = PWR_BANDGAP | PWR_RECEIVER | PWR_MEASURE | PWR_INT_OSC;
REG_WRITE(ADDRESS_POWER, &REG_POWER, 1);
dev->delay_ms(2);
/* read cc1 */
REG_SWITCHES0 = PDWN1 | PDWN2 | MEAS_CC1;
REG_SWITCHES1 = SPECREV0;
REG_MEASURE = 49;
REG_WRITE(ADDRESS_SWITCHES0, &REG_SWITCHES0, 3);
dev->delay_ms(2);
while (FUSB302_read_cc_lvl(dev, &dev->cc1) != FUSB302_SUCCESS) {
dev->delay_ms(2);
}
/* read cc2 */
REG_SWITCHES0 = PDWN1 | PDWN2 | MEAS_CC2;
REG_WRITE(ADDRESS_SWITCHES0, &REG_SWITCHES0, 1);
dev->delay_ms(2);
while (FUSB302_read_cc_lvl(dev, &dev->cc2) != FUSB302_SUCCESS) {
dev->delay_ms(2);
}
/* clear interrupt */
REG_READ(ADDRESS_INTERRUPTA, &REG_INTERRUPTA, 2);
dev->interrupta = 0;
dev->interruptb = 0;
/* enable tx on cc pin */
if (dev->cc1 > 0) {
REG_SWITCHES0 = PDWN1 | PDWN2 | MEAS_CC1;
REG_SWITCHES1 = SPECREV0 | AUTO_CRC | TXCC1;
//REG_SWITCHES1 = SPECREV0 | TXCC1;
} else if (dev->cc2 > 0) {
REG_SWITCHES0 = PDWN1 | PDWN2 | MEAS_CC2;
REG_SWITCHES1 = SPECREV0 | AUTO_CRC | TXCC2;
//REG_SWITCHES1 = SPECREV0 | TXCC2;
} else {
REG_SWITCHES0 = PDWN1 | PDWN2;
REG_SWITCHES1 = SPECREV0;
}
REG_WRITE(ADDRESS_SWITCHES0, &REG_SWITCHES0, 2);
/* update state */
dev->state = FUSB302_STATE_ATTACHED;
if (events) {
*events |= FUSB302_EVENT_ATTACHED;
}
}
return FUSB302_SUCCESS;
}
static FUSB302_ret_t FUSB302_state_attached(FUSB302_dev_t *dev, FUSB302_event_t * events)
{
REG_READ(ADDRESS_STATUS0A, &REG_STATUS0A, 7);
dev->interrupta |= REG_INTERRUPTA;
dev->interruptb |= REG_INTERRUPTB;
if (dev->vbus_sense && ((REG_STATUS0 & VBUSOK) == 0)) {
/* reset cc pins to pull down */
REG_SWITCHES0 = PDWN1 | PDWN2;
REG_SWITCHES1 = SPECREV0;
REG_MEASURE = 49;
REG_WRITE(ADDRESS_SWITCHES0, &REG_SWITCHES0, 3);
/* turn off internal oscillator */
REG_POWER = PWR_BANDGAP | PWR_RECEIVER | PWR_MEASURE;
REG_WRITE(ADDRESS_POWER, &REG_POWER, 1);
/* update state */
dev->state = FUSB302_STATE_UNATTACHED;
if (events) {
*events |= FUSB302_EVENT_DETACHED;
}
return FUSB302_SUCCESS;
}
if (REG_STATUS0A & HARDRST) {
uint8_t reg_control = PD_RESET;
REG_WRITE(ADDRESS_RESET, &reg_control, 1);
return FUSB302_SUCCESS;
}
if (dev->interruptb & I_GCRCSENT) {
dev->interruptb &= ~I_GCRCSENT;
if (events) {
*events |= FUSB302_EVENT_GOOD_CRC_SENT;
}
}
if ((REG_STATUS1 & RX_EMPTY) == 0) {
if (FUSB302_read_incoming_packet(dev, events) != FUSB302_SUCCESS) {
uint8_t rx_flush = REG_CONTROL1 | RX_FLUSH;
reg_write(dev, ADDRESS_CONTROL1, &rx_flush, 1);
}
}
return FUSB302_SUCCESS;
}
FUSB302_ret_t FUSB302_init(FUSB302_dev_t *dev)
{
if (dev->i2c_address == 0) {
dev->err_msg = FUSB302_ERR_MSG("Invalid i2c address");
return FUSB302_ERR_PARAM;
}
if (dev->i2c_read == 0) {
dev->err_msg = FUSB302_ERR_MSG("Invalid i2c_read function");
return FUSB302_ERR_PARAM;
}
if (dev->i2c_write == 0) {
dev->err_msg = FUSB302_ERR_MSG("Invalid i2c_write function");
return FUSB302_ERR_PARAM;
}
if (reg_read(dev, ADDRESS_DEVICE_ID, &dev->reg_control[1], 1) != FUSB302_SUCCESS) {
dev->err_msg = FUSB302_ERR_MSG("Device not found");
return FUSB302_ERR_READ_DEVICE;
}
if ((dev->reg_control[1] & 0x80) == 0) {
dev->err_msg = FUSB302_ERR_MSG("Invalid device version");
return FUSB302_ERR_DEVICE_ID;
}
dev->state = FUSB302_STATE_UNATTACHED;
dev->rx_header = 0;
memset(dev->rx_buffer, 0, sizeof(dev->rx_buffer));
/* restore default settings */
REG_RESET = SW_RES;
REG_WRITE(ADDRESS_RESET, &REG_RESET, 1);
/* fetch all R/W registers */
REG_READ(ADDRESS_DEVICE_ID, &REG_DEVICE_ID, 15);
/* configure switchs and comparators */
REG_SWITCHES0 = PDWN1 | PDWN2;
REG_SWITCHES1 = SPECREV0;
REG_MEASURE = 49;
REG_WRITE(ADDRESS_SWITCHES0, &REG_SWITCHES0, 3);
/* configure auto retries */
REG_CONTROL3 &= ~N_RETRIES_MASK;
REG_CONTROL3 |= N_RETRIES(3) | AUTO_RETRY;
REG_WRITE(ADDRESS_CONTROL3, &REG_CONTROL3, 1);
/* configure interrupt mask */
REG_MASK = 0xFF;
REG_MASK &= ~(M_VBUSOK | M_ACTIVITY | M_COLLISION | M_ALERT | M_CRC_CHK);
REG_WRITE(ADDRESS_MASK, &REG_MASK, 1);
/* configure interrupt maska/maskb */
REG_MASKA = 0xFF;
REG_MASKA &= ~(M_RETRYFAIL | M_HARDSENT | M_TXSENT | M_HARDRST);
REG_WRITE(ADDRESS_MASKA, &REG_MASKA, 1);
REG_MASKB = 0xFF;
REG_MASKB &= ~(M_GCRCSENT);
REG_WRITE(ADDRESS_MASKB, &REG_MASKB, 1);
/* enable interrupt */
REG_CONTROL0 &= ~INT_MASK;
REG_WRITE(ADDRESS_CONTROL0, &REG_CONTROL0, 1);
/* Power on, enable VUSB detection */
REG_POWER = PWR_BANDGAP | PWR_RECEIVER | PWR_MEASURE;
REG_WRITE(ADDRESS_POWER, &REG_POWER, 1);
dev->vbus_sense = 1;
dev->err_msg = FUSB302_ERR_MSG("");
return FUSB302_SUCCESS;
}
FUSB302_ret_t FUSB302_pd_reset(FUSB302_dev_t *dev)
{
uint8_t reg = PD_RESET;
REG_WRITE(ADDRESS_RESET, &reg, 1);
return FUSB302_SUCCESS;
}
FUSB302_ret_t FUSB302_pdwn_cc(FUSB302_dev_t *dev, uint8_t enable)
{
REG_SWITCHES0 = enable ? (PDWN1 | PDWN2) : 0;
REG_WRITE(ADDRESS_SWITCHES0, &REG_SWITCHES0, 1);
return FUSB302_SUCCESS;
}
FUSB302_ret_t FUSB302_set_vbus_sense(FUSB302_dev_t *dev, uint8_t enable)
{
if (dev->vbus_sense != enable) {
if (enable) {
REG_MASK &= ~M_VBUSOK; /* enable VBUSOK interrupt */
} else {
REG_MASK |= M_VBUSOK; /* disable VBUSOK interrupt */
}
REG_WRITE(ADDRESS_MASK, &REG_MASK, 1);
dev->vbus_sense = enable;
}
return FUSB302_SUCCESS;
}
FUSB302_ret_t FUSB302_get_ID(FUSB302_dev_t *dev, uint8_t * version_ID, uint8_t * revision_ID)
{
if (dev && (REG_DEVICE_ID & 0x80)) {
if (version_ID) {
*version_ID = (REG_DEVICE_ID >> 4) & 0x7;
}
if (revision_ID) {
*revision_ID = (REG_DEVICE_ID >> 0) & 0xF;
}
return FUSB302_SUCCESS;
}
return FUSB302_ERR_PARAM;
}
FUSB302_ret_t FUSB302_get_cc(FUSB302_dev_t *dev, uint8_t *cc1, uint8_t *cc2)
{
if (cc1) {
*cc1 = dev->cc1;
}
if (cc2) {
*cc2 = dev->cc2;
}
return FUSB302_SUCCESS;
}
FUSB302_ret_t FUSB302_get_vbus_level(FUSB302_dev_t *dev, uint8_t *vbus)
{
uint8_t reg_control;
REG_READ(ADDRESS_STATUS0, &reg_control, 1);
*vbus = reg_control & VBUSOK ? 1 : 0;
return FUSB302_SUCCESS;
}
FUSB302_ret_t FUSB302_get_message(FUSB302_dev_t *dev, uint16_t * header, uint32_t * data)
{
if (header) {
*header = dev->rx_header;
}
if (data) {
uint8_t len = (dev->rx_header >> 12) & 0x7;
memcpy(data, dev->rx_buffer, len * 4);
}
return FUSB302_SUCCESS;
}
FUSB302_ret_t FUSB302_tx_sop(FUSB302_dev_t *dev, uint16_t header, const uint32_t *data)
{
uint8_t buf[40];
uint8_t * pbuf = buf;
uint8_t obj_count = ((header >> 12) & 7);
*pbuf++ = (uint8_t)TX_TOKEN_SOP1;
*pbuf++ = (uint8_t)TX_TOKEN_SOP1;
*pbuf++ = (uint8_t)TX_TOKEN_SOP1;
*pbuf++ = (uint8_t)TX_TOKEN_SOP2;
*pbuf++ = (uint8_t)TX_TOKEN_PACKSYM | ((obj_count << 2) + 2);
*pbuf++ = header & 0xFF; header >>= 8;
*pbuf++ = header & 0xFF;
for (uint8_t i = 0; i < obj_count; i++) {
uint32_t d = *data++;
*pbuf++ = d & 0xFF; d >>= 8;
*pbuf++ = d & 0xFF; d >>= 8;
*pbuf++ = d & 0xFF; d >>= 8;
*pbuf++ = d & 0xFF;
}
*pbuf++ = (uint8_t)TX_TOKEN_JAM_CRC;
*pbuf++ = (uint8_t)TX_TOKEN_EOP;
*pbuf++ = (uint8_t)TX_TOKEN_TXOFF;
*pbuf++ = (uint8_t)TX_TOKEN_TXON;
REG_WRITE(ADDRESS_FIFOS, buf, pbuf - buf);
dev->delay_ms(2);
return FUSB302_SUCCESS;
}
FUSB302_ret_t FUSB302_tx_hard_reset(FUSB302_dev_t *dev)
{
uint8_t reg_control = REG_CONTROL3;
reg_control |= SEND_HARDRESET;
REG_WRITE(ADDRESS_CONTROL3, &reg_control, 1);
dev->delay_ms(6);
reg_control = PD_RESET;
REG_WRITE(ADDRESS_RESET, &reg_control, 1);
return FUSB302_SUCCESS;
}
FUSB302_ret_t FUSB302_alert(FUSB302_dev_t *dev, FUSB302_event_t * events)
{
FUSB302_ret_t (* const handler[]) (FUSB302_dev_t *, FUSB302_event_t *) = {
FUSB302_state_unattached,
FUSB302_state_attached
};
if (dev->state < sizeof(handler) / sizeof(handler[0])) {
return handler[dev->state](dev, events);
}
dev->state = FUSB302_STATE_UNATTACHED;
return FUSB302_SUCCESS;
}

View File

@@ -1,76 +0,0 @@
/**
* FUSB302_UFP.h
*
* Updated on: Jan 4, 2021
* Author: Ryan Ma
*
* Minimalist USB PD implement with only UFP(device) functionality
* Requires only stdint.h and string.h
* No use of bit-field for better cross-platform compatibility
*
* FUSB302 can support PD3.0 with limitations and workarounds
* - Do not have enough FIFO for unchunked message, use chunked message instead
* - VBUS sense low threshold at 4V, disable vbus_sense if request PPS below 4V
*
*/
#ifndef FUSB302_UFP_H
#define FUSB302_UFP_H
#include <stdint.h>
enum {
FUSB302_SUCCESS = 0,
FUSB302_BUSY = (1 << 0),
FUSB302_ERR_PARAM = (1 << 1),
FUSB302_ERR_DEVICE_ID = (1 << 2),
FUSB302_ERR_READ_DEVICE = (1 << 3),
FUSB302_ERR_WRITE_DEVICE = (1 << 4)
};
typedef uint8_t FUSB302_ret_t;
#define FUSB302_EVENT_ATTACHED (1 << 0)
#define FUSB302_EVENT_DETACHED (1 << 1)
#define FUSB302_EVENT_RX_SOP (1 << 2)
#define FUSB302_EVENT_GOOD_CRC_SENT (1 << 3)
typedef uint8_t FUSB302_event_t;
typedef struct {
/* setup by user */
uint8_t i2c_address;
FUSB302_ret_t (*i2c_read)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t count);
FUSB302_ret_t (*i2c_write)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t count);
FUSB302_ret_t (*delay_ms)(uint32_t t);
/* used by this library */
const char * err_msg;
uint16_t rx_header;
uint8_t rx_buffer[32];
uint8_t reg_control[15];
uint8_t reg_status[7];
uint8_t interrupta;
uint8_t interruptb;
uint8_t cc1;
uint8_t cc2;
uint8_t state;
uint8_t vbus_sense;
} FUSB302_dev_t;
static inline const char * FUSB302_get_last_err_msg(FUSB302_dev_t *dev) { return dev->err_msg; }
FUSB302_ret_t FUSB302_init (FUSB302_dev_t *dev);
FUSB302_ret_t FUSB302_pd_reset (FUSB302_dev_t *dev);
FUSB302_ret_t FUSB302_pdwn_cc (FUSB302_dev_t *dev, uint8_t enable);
FUSB302_ret_t FUSB302_set_vbus_sense (FUSB302_dev_t *dev, uint8_t enable);
FUSB302_ret_t FUSB302_get_ID (FUSB302_dev_t *dev, uint8_t *version_ID, uint8_t *revision_ID);
FUSB302_ret_t FUSB302_get_cc (FUSB302_dev_t *dev, uint8_t *cc1, uint8_t *cc2);
FUSB302_ret_t FUSB302_get_vbus_level (FUSB302_dev_t *dev, uint8_t *vbus);
FUSB302_ret_t FUSB302_get_message (FUSB302_dev_t *dev, uint16_t *header, uint32_t *data);
FUSB302_ret_t FUSB302_tx_sop (FUSB302_dev_t *dev, uint16_t header, const uint32_t *data);
FUSB302_ret_t FUSB302_tx_hard_reset (FUSB302_dev_t *dev);
FUSB302_ret_t FUSB302_alert (FUSB302_dev_t *dev, FUSB302_event_t *events);
#endif /* FUSB302_H */

View File

@@ -1,599 +0,0 @@
/**
* PD_UFP_Protocol.c
*
* Updated on: Jan 25, 2021
* Author: Ryan Ma
*
* Minimalist USB PD implement with only UFP(device) sink only functionality
* Requires PD PHY to do automatic GoodCRC response on valid SOP messages.
* Requires only stdint.h, stdbool.h and string.h
* No use of bit-field for better cross-platform compatibility
*
* Support PD3.0 PPS
* Do not support extended message. Not necessary for PD trigger and PPS.
*
* Reference: USB_PD_R2_0 V1.3 - 20170112
* USB_PD_R3_0 V2.0 20190829 + ECNs 2020-12-10
* - Chapter 6. Protocol Layer
*
*/
#include <string.h>
#include "PD_UFP_Protocol.h"
#define PD_SPECIFICATION_REVISION 0x2
#define PD_CONTROL_MSG_TYPE_ACCEPT 0x3
#define PD_CONTROL_MSG_TYPE_REJECT 0x4
#define PD_CONTROL_MSG_TYPE_GET_SRC_CAP 0x7
#define PD_CONTROL_MSG_TYPE_NOT_SUPPORT 0x10
#define PD_CONTROL_MSG_TYPE_GET_PPS_STATUS 0x14
#define PD_DATA_MSG_TYPE_REQUEST 0x2
#define PD_DATA_MSG_TYPE_SINK_CAP 0x4
#define PD_DATA_MSG_TYPE_VENDOR_DEFINED 0xF
#define PD_EXT_MSG_TYPE_SINK_CAP_EXT 0xF
typedef struct {
uint8_t type;
uint8_t spec_rev;
uint8_t id;
uint8_t num_of_obj;
} PD_msg_header_info_t;
typedef struct {
uint16_t limit;
uint8_t use_voltage;
uint8_t use_current;
} PD_power_option_setting_t;
struct PD_msg_state_t {
const char * name;
void (*handler)(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
bool (*responder)(PD_protocol_t * p, uint16_t * header, uint32_t * obj);
};
/* Optimize RAM usage on AVR MCU by allocate const in PROGMEM */
#if defined(__AVR__)
#include <avr/pgmspace.h>
#define SET_MSG_STAGE(d, s) do { static struct PD_msg_state_t m; memcpy_P(&m, s, sizeof(struct PD_msg_state_t)); d = &m; } while (0)
#define SET_MSG_NAME(d, s) do { static char n[16]; strncpy_P(n, s, 15); d = n; } while (0)
#define COPY_PDO(d, s) do { memcpy_P(&d, &s, 4); } while (0)
#else
#define PROGMEM
#define SET_MSG_STAGE(d, s) do { d = s; } while (0)
#define SET_MSG_NAME(d, s) do { d = s; } while (0)
#define COPY_PDO(d, s) do { d = s; } while (0)
#endif
#define T(name) static const char str_ ## name [] PROGMEM = #name
static void handler_good_crc (PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
static void handler_goto_min (PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
static void handler_accept (PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
static void handler_reject (PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
static void handler_ps_rdy (PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
static void handler_source_cap (PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
static void handler_BIST (PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
static void handler_alert (PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
static void handler_vender_def (PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
static void handler_PPS_Status (PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events);
static bool responder_get_sink_cap (PD_protocol_t * p, uint16_t * header, uint32_t * obj);
static bool responder_reject (PD_protocol_t * p, uint16_t * header, uint32_t * obj);
static bool responder_soft_reset (PD_protocol_t * p, uint16_t * header, uint32_t * obj);
static bool responder_source_cap (PD_protocol_t * p, uint16_t * header, uint32_t * obj);
static bool responder_vender_def (PD_protocol_t * p, uint16_t * header, uint32_t * obj);
static bool responder_sink_cap_ext (PD_protocol_t * p, uint16_t * header, uint32_t * obj);
static bool responder_not_support (PD_protocol_t * p, uint16_t * header, uint32_t * obj);
T(C0); T(GoodCRC); T(GotoMin); T(Accept); T(Reject); T(Ping); T(PS_RDY); T(Get_Src_Cap);
T(Get_Sink_Cap); T(DR_Swap); T(PR_Swap); T(VCONN_Swap); T(Wait); T(Soft_Rst); T(Dat_Rst); T(Dat_Rst_Cpt);
T(NS); T(Get_Src_Ext); T(Get_Stat); T(FR_Swap); T(Get_PPS_Stat); T(Get_CC); T(Get_Sink_Ext); T(C_R);
static const struct PD_msg_state_t ctrl_msg_list[] PROGMEM = {
{.name = str_C0, .handler = 0, .responder = 0},
{.name = str_GoodCRC, .handler = handler_good_crc, .responder = 0},
{.name = str_GotoMin, .handler = handler_goto_min, .responder = 0},
{.name = str_Accept, .handler = handler_accept, .responder = 0},
{.name = str_Reject, .handler = handler_reject, .responder = 0},
{.name = str_Ping, .handler = 0, .responder = 0},
{.name = str_PS_RDY, .handler = handler_ps_rdy, .responder = 0},
{.name = str_Get_Src_Cap, .handler = 0, .responder = responder_not_support},
{.name = str_Get_Sink_Cap, .handler = 0, .responder = responder_get_sink_cap},
{.name = str_DR_Swap, .handler = 0, .responder = responder_reject},
{.name = str_PR_Swap, .handler = 0, .responder = responder_not_support},
{.name = str_VCONN_Swap, .handler = 0, .responder = responder_reject},
{.name = str_Wait, .handler = 0, .responder = 0},
{.name = str_Soft_Rst, .handler = 0, .responder = responder_soft_reset},
{.name = str_Dat_Rst, .handler = 0, .responder = 0},
{.name = str_Dat_Rst_Cpt, .handler = 0, .responder = 0},
{.name = str_NS, .handler = 0, .responder = 0},
{.name = str_Get_Src_Ext, .handler = 0, .responder = responder_not_support},
{.name = str_Get_Stat, .handler = 0, .responder = responder_not_support},
{.name = str_FR_Swap, .handler = 0, .responder = responder_not_support},
{.name = str_Get_PPS_Stat, .handler = 0, .responder = responder_not_support},
{.name = str_Get_CC, .handler = 0, .responder = responder_not_support},
{.name = str_Get_Sink_Ext, .handler = 0, .responder = responder_sink_cap_ext},
{.name = str_C_R, .handler = 0, .responder = responder_not_support},
};
T(D0); T(Src_Cap); T(Request); T(BIST); T(Sink_Cap); T(Bat_Stat); T(Alert); T(Get_CI);
T(Enter_USB); T(D9); T(D10); T(D11); T(D12); T(D13); T(D14); T(VDM);
T(D_R);
static const struct PD_msg_state_t data_msg_list[] PROGMEM = {
{.name = str_D0, .handler = 0, .responder = 0},
{.name = str_Src_Cap, .handler = handler_source_cap, .responder = responder_source_cap},
{.name = str_Request, .handler = 0, .responder = responder_not_support},
{.name = str_BIST, .handler = handler_BIST, .responder = 0},
{.name = str_Sink_Cap, .handler = 0, .responder = responder_not_support},
{.name = str_Bat_Stat, .handler = 0, .responder = responder_not_support},
{.name = str_Alert, .handler = handler_alert, .responder = 0},
{.name = str_Get_CI, .handler = 0, .responder = responder_not_support},
{.name = str_Enter_USB, .handler = 0, .responder = 0},
{.name = str_D9, .handler = 0, .responder = 0},
{.name = str_D10, .handler = 0, .responder = 0},
{.name = str_D11, .handler = 0, .responder = 0},
{.name = str_D12, .handler = 0, .responder = 0},
{.name = str_D13, .handler = 0, .responder = 0},
{.name = str_D14, .handler = 0, .responder = 0},
{.name = str_VDM, .handler = handler_vender_def, .responder = responder_vender_def},
{.name = str_D_R, .handler = 0, .responder = responder_not_support},
};
T(E0); T(Src_Cap_Ext); T(Status); T(Get_Bat_cap); T(Get_Bat_Stat); T(Bat_Cap); T(Get_Mfg_Info); T(Mfg_Info);
T(Sec_Request); T(Sec_Response); T(FU_request); T(FU_Response); T(PPS_Stat); T(Country_Info); T(Country_Code); T(Sink_Cap_Ext);
T(E_R);
static const struct PD_msg_state_t ext_msg_list[] PROGMEM = {
{.name = str_E0, .handler = 0, .responder = responder_not_support},
{.name = str_Src_Cap_Ext, .handler = 0, .responder = 0},
{.name = str_Status, .handler = 0, .responder = 0},
{.name = str_Get_Bat_cap, .handler = 0, .responder = responder_not_support},
{.name = str_Get_Bat_Stat, .handler = 0, .responder = responder_not_support},
{.name = str_Bat_Cap, .handler = 0, .responder = 0},
{.name = str_Get_Mfg_Info, .handler = 0, .responder = responder_not_support},
{.name = str_Mfg_Info, .handler = 0, .responder = 0},
{.name = str_Sec_Request, .handler = 0, .responder = responder_not_support},
{.name = str_Sec_Response, .handler = 0, .responder = 0},
{.name = str_FU_request, .handler = 0, .responder = responder_not_support},
{.name = str_FU_Response, .handler = 0, .responder = 0},
{.name = str_PPS_Stat, .handler = handler_PPS_Status, .responder = 0},
{.name = str_Country_Info, .handler = 0, .responder = 0},
{.name = str_Country_Code, .handler = 0, .responder = 0},
{.name = str_Sink_Cap_Ext, .handler = 0, .responder = responder_not_support},
{.name = str_E_R, .handler = 0, .responder = responder_not_support},
};
static const PD_power_option_setting_t power_option_setting[8] = {
{.limit = 25, .use_voltage = 1, .use_current = 0}, /* PD_POWER_OPTION_MAX_5V */
{.limit = 45, .use_voltage = 1, .use_current = 0}, /* PD_POWER_OPTION_MAX_9V */
{.limit = 60, .use_voltage = 1, .use_current = 0}, /* PD_POWER_OPTION_MAX_12V */
{.limit = 75, .use_voltage = 1, .use_current = 0}, /* PD_POWER_OPTION_MAX_15V */
{.limit = 100, .use_voltage = 1, .use_current = 0}, /* PD_POWER_OPTION_MAX_20V */
{.limit = 100, .use_voltage = 1, .use_current = 0}, /* PD_POWER_OPTION_MAX_VOLTAGE */
{.limit = 125, .use_voltage = 0, .use_current = 1}, /* PD_POWER_OPTION_MAX_CURRENT */
{.limit = 12500,.use_voltage = 1, .use_current = 1}, /* PD_POWER_OPTION_MAX_POWER */
};
static uint8_t evaluate_src_cap(PD_protocol_t * p, uint16_t PPS_voltage, uint8_t PPS_current)
{
const PD_power_option_setting_t * setting;
PD_power_info_t info;
uint8_t option = p->power_option;
uint8_t selected = 0;
/* If selected option is not available, use first PDO. Reference: 6.4.1 Capabilities Message
The vSafe5V Fixed Supply Object Shall always be the first object. */
if (option >= sizeof(power_option_setting) / sizeof(power_option_setting[0])) {
return 0;
}
setting = &power_option_setting[option];
for (uint8_t n = 0; PD_protocol_get_power_info(p, n, &info); n++) {
if (info.type == PD_PDO_TYPE_AUGMENTED_PDO) {
uint16_t pps_v = PPS_voltage * 2; /* Voltage in 20mV units */
uint16_t pps_i = PPS_current * 5; /* Current in 50mA units */
/* PD_power_info_t: Voltage in 50mV units, Current in 10mA units */
if (info.min_v * 5 <= pps_v && pps_v <= info.max_v * 5 && pps_i <= info.max_i) {
return n;
}
} else {
uint8_t v = setting->use_voltage ? info.max_v >> 2 : 1;
uint8_t i = setting->use_current ? info.max_i >> 2 : 1;
uint16_t power = (uint16_t)v * i; /* reduce 10-bit power info to 8-bit and use 8-bit x 8-bit multiplication */
if (power <= setting->limit) {
selected = n;
}
}
}
return selected;
}
static void parse_header(PD_msg_header_info_t * info, uint16_t header)
{
/* Reference: 6.2.1.1 Message Header */
info->type = (header >> 0) & 0x1F; /* 4...0 Message Type */
info->spec_rev = (header >> 6) & 0x3; /* 7...6 Specification Revision */
info->id = (header >> 9) & 0x7; /* 11...9 MessageID */
info->num_of_obj = (header >> 12) & 0x7; /* 14...12 Number of Data Objects */
}
static uint16_t generate_header(PD_protocol_t * p, uint8_t type, uint8_t obj_count)
{
/* Reference: 6.2.1.1 Message Header */
uint16_t h = ((uint16_t)type << 0) | /* 4...0 Message Type */
((uint16_t)PD_SPECIFICATION_REVISION << 6) | /* 7...6 Specification Revision */
((uint16_t)p->message_id << 9) | /* 11...9 MessageID */
((uint16_t)obj_count << 12); /* 14...12 Number of Data Objects */
p->tx_msg_header = h;
return h;
}
static uint16_t generate_header_ext(PD_protocol_t * p, uint8_t type, uint8_t data_size, uint32_t * obj)
{
uint16_t h = generate_header(p, type, (data_size + 5) >> 2); /* set obj_count to fit ext header and data */
h |= (uint16_t)1 << 15; /* Set extended field */
/* Reference: 6.2.1.2 Extended Message Headerr */
obj[0] |= ((uint16_t)data_size << 0) | /* 8...0 ata Size */
/* Assume short message, set Chunk Number and Request Chunk to 0 */
((uint16_t)1 << 15); /* 15 Chunked */
p->tx_msg_header = h;
return h;
}
static void handler_good_crc(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
/* Reference: 6.2.1.3 Message ID
MessageIDCounter Shall be initialized to zero at power-on / reset, increment when receive GoodCRC Message */
uint8_t message_id = p->message_id;
if (++message_id > 7) {
message_id = 0;
}
p->message_id = message_id;
}
static void handler_goto_min(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
// Not implemented
}
static void handler_accept(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
if (events) {
*events |= PD_PROTOCOL_EVENT_ACCEPT;
}
}
static void handler_reject(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
if (events) {
*events |= PD_PROTOCOL_EVENT_PS_RDY;
}
}
static void handler_ps_rdy(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
if (events) {
*events |= PD_PROTOCOL_EVENT_PS_RDY;
}
}
static void handler_source_cap(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
PD_msg_header_info_t h;
parse_header(&h, header);
p->power_data_obj_count = h.num_of_obj;
for (uint8_t i = 0; i < h.num_of_obj; i++) {
p->power_data_obj[i] = obj[i];
}
p->power_data_obj_selected = evaluate_src_cap(p, p->PPS_voltage, p->PPS_current);
if (events) {
*events |= PD_PROTOCOL_EVENT_SRC_CAP;
}
}
static void handler_BIST(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
// TODO: implement BIST
}
static void handler_alert(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
// TODO: implement alert
}
static void handler_vender_def(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
// TODO: implement VDM parsing
}
static void handler_PPS_Status(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
/* Handle chunked Extended message, Offset 2 byte for Extended Message Header */
p->PPSSDB[0] = (obj[0] >> 16) & 0xFF;
p->PPSSDB[1] = (obj[0] >> 24) & 0xFF;
p->PPSSDB[2] = (obj[1] >> 0) & 0xFF;
p->PPSSDB[3] = (obj[1] >> 8) & 0xFF;
if (events) {
*events |= PD_PROTOCOL_EVENT_PPS_STATUS;
}
}
static bool responder_get_sink_cap(PD_protocol_t * p, uint16_t * header, uint32_t * obj)
{
/* Reference: 6.4.1.2.3 Sink Fixed Supply Power Data Object */
uint32_t data = ((uint32_t)100 << 0) | /* B9...0 Operational Current in 10mA units */
((uint32_t)100 << 10) | /* B19...10 Voltage in 50mV units */
((uint32_t)1 << 26) | /* B26 USB Communications Capable */
((uint32_t)1 << 28) | /* B28 Higher Capability */
((uint32_t)PD_PDO_TYPE_FIXED_SUPPLY << 30); /* B31...30 Fixed supply */
*obj = data; /* Only implement 5V 1A Fix supply PDO. Source rarely request sink cap */
*header = generate_header(p, PD_DATA_MSG_TYPE_SINK_CAP, 1);
return true;
}
static bool responder_sink_cap_ext(PD_protocol_t * p, uint16_t * header, uint32_t * obj)
{
/* Reference: 6.5.13 Sink_Capabilities_Extended Message
6.12.3 Applicability of Extended Messages (Normative; Shall be supported) */
#define SINK_CAP_VID 0
#define SINK_CAP_PID 0
#define SINK_CAP_XID 0 /* If the vendor does not have an XID, then it Shall return zero */
#define SINK_CAP_FW_Version 1
#define SINK_CAP_HW_Version 1
#define SINK_CAP_SKEDB_Version 1
#define SINK_CAP_SINK_MODE 0x3 /* Bit 0: PPS charging supported, Bit 1: VBUS powered */
#define SINK_CAP_SINK_MIN_PDP 5 /* Minimum PD Power in Watt */
#define SINK_CAP_SINK_OP_PDP 5 /* Operational PD Power in Watt */
#define SINK_CAP_SINK_MAX_PDP 100 /* Maximum PD Power in Watt */
static const uint32_t SKEDB[6] PROGMEM = { /* 2-byte header + 21-byte data, chunked to 6 PDO */
/* PDO[0], data byte 0...1 */
/* 16-bit LSB is reserved for Extended Message Header */
((uint32_t)SINK_CAP_VID << 16), /* Byte 0...1 VID */
/* PDO[1], data byte 2...5 */
((uint32_t)SINK_CAP_PID << 0) | /* Byte 2...3 PID */
(((uint32_t)SINK_CAP_XID & 0xFF) << 16), /* Byte 4...5 XID */
/* PDO[2], data byte 6...9 */
(((uint32_t)SINK_CAP_XID >> 16) << 0) | /* Byte 6...7 XID */
((uint32_t)SINK_CAP_FW_Version << 16) | /* Byte 8 FW Version */
((uint32_t)SINK_CAP_HW_Version << 24), /* Byte 9 HW Version */
/* PDO[3], data byte 10...13 */
((uint32_t)SINK_CAP_SKEDB_Version << 0), /* Byte 10 SKEDB Version */
/* Not set Byte 11 Load Step, Byte 13..12 Sink Load Characteristics */
/* PDO[4], data byte 14...17 */
/* Not set Byte 14 Compliance, Byte 15 Touch Temp, Byte 16 Battery Info */
((uint32_t)SINK_CAP_SINK_MODE << 24), /* Byte 17 Sink Modes */
/* PDO[5], data byte 18...20 */
((uint32_t)SINK_CAP_SINK_MIN_PDP << 0) | /* Byte 18 Minimum PDP */
((uint32_t)SINK_CAP_SINK_OP_PDP << 8) | /* Byte 19 Operational PDP */
((uint32_t)SINK_CAP_SINK_MAX_PDP << 16) /* Byte 20 Maximum PDP */
};
uint8_t i;
for (i = 0; i < 6; i++) {
COPY_PDO(obj[i], SKEDB[i]);
}
*header = generate_header_ext(p, PD_EXT_MSG_TYPE_SINK_CAP_EXT, 21, obj);
return false;
}
static bool responder_reject(PD_protocol_t * p, uint16_t * header, uint32_t * obj)
{
*header = generate_header(p, PD_CONTROL_MSG_TYPE_REJECT, 0);
return true;
}
static bool responder_not_support(PD_protocol_t * p, uint16_t * header, uint32_t * obj)
{
*header = generate_header(p, PD_CONTROL_MSG_TYPE_NOT_SUPPORT, 0);
return true;
}
static bool responder_soft_reset(PD_protocol_t * p, uint16_t * header, uint32_t * obj)
{
*header = generate_header(p, PD_CONTROL_MSG_TYPE_ACCEPT, 0);
return true;
}
static bool responder_source_cap(PD_protocol_t * p, uint16_t * header, uint32_t * obj)
{
PD_power_info_t info;
uint32_t data, pos = p->power_data_obj_selected + 1;
PD_protocol_get_power_info(p, p->power_data_obj_selected, &info);
/* Reference: 6.4.2 Request Message */
if (info.type == PD_PDO_TYPE_AUGMENTED_PDO) {
/* NOTE: To compatible PD2.0 PHY, do not set Unchunked Extended Messages Supported */
data = ((uint32_t)p->PPS_current << 0) | /* B6 ...0 Operating Current 50mA units */
((uint32_t)p->PPS_voltage << 9) | /* B19...9 Output Voltage in 20mV units */
((uint32_t)1 << 25) | /* B25 USB Communication Capable */
((uint32_t)pos << 28); /* B30...28 Object position (000b is Reserved and Shall Not be used) */
} else {
uint32_t req = info.max_i ? info.max_i : info.max_p;
data = ((uint32_t)req << 0) | /* B9 ...0 Max Operating Current 10mA units / Max Operating Power in 250mW units */
((uint32_t)req << 10) | /* B19...10 Operating Current 10mA units / Operating Power in 250mW units */
((uint32_t)1 << 25) | /* B25 USB Communication Capable */
((uint32_t)pos << 28); /* B30...28 Object position (000b is Reserved and Shall Not be used) */
}
*obj = data;
*header = generate_header(p, PD_DATA_MSG_TYPE_REQUEST, 1);
return true;
}
static bool responder_vender_def(PD_protocol_t * p, uint16_t * header, uint32_t * obj)
{
// TODO: implement VDM respond
return false;
}
void PD_protocol_handle_msg(PD_protocol_t * p, uint16_t header, uint32_t * obj, PD_protocol_event_t * events)
{
#define EXT_MSG_LIMIT (sizeof(ext_msg_list) / sizeof(ext_msg_list[0]) - 1)
#define DATA_MSG_LIMIT (sizeof(data_msg_list) / sizeof(data_msg_list[0]) - 1)
#define CTRL_MSG_LIMIT (sizeof(ctrl_msg_list) / sizeof(ctrl_msg_list[0]) - 1)
const struct PD_msg_state_t * state;
PD_msg_header_info_t h;
parse_header(&h, header);
p->rx_msg_header = header;
if ((header >> 15) & 0x1) {
state = &ext_msg_list[h.type > EXT_MSG_LIMIT ? EXT_MSG_LIMIT : h.type];
} else if (h.num_of_obj) {
state = &data_msg_list[h.type > DATA_MSG_LIMIT ? DATA_MSG_LIMIT : h.type];
} else {
state =&ctrl_msg_list[h.type > CTRL_MSG_LIMIT ? CTRL_MSG_LIMIT : h.type];
}
SET_MSG_STAGE(p->msg_state, state);
if (p->msg_state->handler) {
p->msg_state->handler(p, header, obj, events);
}
}
bool PD_protocol_respond(PD_protocol_t * p, uint16_t * header, uint32_t * obj)
{
if (p && p->msg_state && p->msg_state->responder && header && obj) {
return p->msg_state->responder(p, (uint16_t *)header, obj);
}
return false;
}
void PD_protocol_create_get_src_cap(PD_protocol_t * p, uint16_t * header)
{
*header = generate_header(p, PD_CONTROL_MSG_TYPE_GET_SRC_CAP, 0);
}
void PD_protocol_create_get_PPS_status(PD_protocol_t *p, uint16_t *header)
{
*header = generate_header(p, PD_CONTROL_MSG_TYPE_GET_PPS_STATUS, 0);
}
void PD_protocol_create_request(PD_protocol_t * p, uint16_t * header, uint32_t * obj)
{
responder_source_cap(p, header, obj);
}
bool PD_protocol_get_power_info(PD_protocol_t * p, uint8_t index, PD_power_info_t * power_info)
{
if (p && index < p->power_data_obj_count && power_info) {
uint32_t obj = p->power_data_obj[index];
power_info->type = obj >> 30;
switch (power_info->type) {
case PD_PDO_TYPE_FIXED_SUPPLY:
/* Reference: 6.4.1.2.3 Source Fixed Supply Power Data Object */
power_info->min_v = 0;
power_info->max_v = (obj >> 10) & 0x3FF; /* B19...10 Voltage in 50mV units */
power_info->max_i = (obj >> 0) & 0x3FF; /* B9 ...0 Max Current in 10mA units */
power_info->max_p = 0;
break;
case PD_PDO_TYPE_BATTERY:
/* Reference: 6.4.1.2.5 Battery Supply Power Data Object */
power_info->min_v = (obj >> 10) & 0x3FF; /* B19...10 Min Voltage in 50mV units */
power_info->max_v = (obj >> 20) & 0x3FF; /* B29...20 Max Voltage in 50mV units */
power_info->max_i = 0;
power_info->max_p = (obj >> 0) & 0x3FF; /* B9 ...0 Max Allowable Power in 250mW units */
break;
case PD_PDO_TYPE_VARIABLE_SUPPLY:
/* Reference: 6.4.1.2.4 Variable Supply (non-Battery) Power Data Object */
power_info->min_v = (obj >> 10) & 0x3FF; /* B19...10 Min Voltage in 50mV units */
power_info->max_v = (obj >> 20) & 0x3FF; /* B29...20 Max Voltage in 50mV units */
power_info->max_i = (obj >> 0) & 0x3FF; /* B9 ...0 Max Current in 10mA units */
power_info->max_p = 0;
break;
case PD_PDO_TYPE_AUGMENTED_PDO:
/* Reference: 6.4.1.3.4 Programmable Power Supply Augmented Power Data Object */
power_info->max_v = ((obj >> 17) & 0xFF) * 2; /* B24...17 Max Voltage in 100mV units */
power_info->min_v = ((obj >> 8) & 0xFF) * 2; /* B15...8 Min Voltage in 100mV units */
power_info->max_i = ((obj >> 0) & 0x7F) * 5; /* B6 ...0 Max Current in 50mA units */
power_info->max_p = 0;
break;
}
return true;
}
return false;
}
bool PD_protocol_get_msg_info(uint16_t header, PD_msg_info_t * msg_info)
{
PD_msg_header_info_t h;
parse_header(&h, header);
if (msg_info) {
const char * name;
const struct PD_msg_state_t * state;
uint8_t type = h.type;
SET_MSG_STAGE(state, header & 0x8000 ? &ext_msg_list[type] :
h.num_of_obj ? &data_msg_list[type] : &ctrl_msg_list[type]);
SET_MSG_NAME(name, state->name);
msg_info->name = name;
msg_info->id = h.id;
msg_info->spec_rev = h.spec_rev;
msg_info->num_of_obj = h.num_of_obj;
msg_info->extended = header >> 15;
return true;
}
return false;
}
bool PD_protocol_get_PPS_status(PD_protocol_t *p, PPS_status_t * PPS_status)
{
if (p && PPS_status) {
/* Reference: 6.5.10 PPS_Status Message */
PPS_status->output_voltage = ((uint16_t)p->PPSSDB[1] << 8) | p->PPSSDB[0];
PPS_status->output_current = p->PPSSDB[2];
PPS_status->flag_PTF = (p->PPSSDB[3] >> 1) & 0x3; /* Bit 1 ... 2 */
PPS_status->flag_OMF = (p->PPSSDB[3] >> 3) & 0x1; /* Bit 3 */
return true;
}
return false;
}
bool PD_protocol_set_power_option(PD_protocol_t * p, enum PD_power_option_t option)
{
p->power_option = option;
p->PPS_voltage = 0;
p->PPS_current = 0;
if (p->power_data_obj_count > 0) {
p->power_data_obj_selected = evaluate_src_cap(p, p->PPS_voltage, p->PPS_current);
return true; /* need to re-send request */
}
return false;
}
bool PD_protocol_select_power(PD_protocol_t * p, uint8_t index)
{
if (index < p->power_data_obj_count) {
p->power_data_obj_selected = index;
return true; /* need to re-send request */
}
return false;
}
bool PD_protocol_set_PPS(PD_protocol_t * p, uint16_t PPS_voltage, uint8_t PPS_current, bool strict)
{
if (p->PPS_voltage != PPS_voltage || p->PPS_current != PPS_current) {
uint8_t selected = evaluate_src_cap(p, PPS_voltage, PPS_current);
if (selected || !strict) {
p->PPS_voltage = PPS_voltage;
p->PPS_current = PPS_current;
p->power_data_obj_selected = selected;
return true; /* need to re-send request */
}
}
return false;
}
void PD_protocol_reset(PD_protocol_t * p)
{
p->msg_state = &ctrl_msg_list[0];
p->message_id = 0;
}
void PD_protocol_init(PD_protocol_t * p)
{
memset(p, 0, sizeof(PD_protocol_t));
p->msg_state = &ctrl_msg_list[0];
}

View File

@@ -1,150 +0,0 @@
/**
* PD_UFP_Protocol.c
*
* Updated on: Aug 25, 2021
* Author: Ryan Ma
*
* Minimalist USB PD implement with only UFP(device) sink only functionality
* Requires PD PHY to do automatic GoodCRC response on valid SOP messages.
* Requires only stdint.h, stdbool.h and string.h
* No use of bit-field for better cross-platform compatibility
*
* Support PD3.0 PPS
* Do not support extended message. Not necessary for PD trigger and PPS.
*
* Reference: USB_PD_R2_0 V1.3 - 20170112
* USB_PD_R3_0 V2.0 20190829 + ECNs 2020-12-10
* - Chapter 6. Protocol Layer
*
*/
#ifndef PD_UFP_PROTOCOL_H
#define PD_UFP_PROTOCOL_H
#include <stdbool.h>
#include <stdint.h>
/* For use in PD_protocol_get_power_info() */
#define PD_V(v) ((uint16_t)(v * 20 + 0.01))
#define PD_A(a) ((uint16_t)(a * 100 + 0.01))
/* For use in PD_protocol_set_PPS_option() */
#define PPS_V(v) ((uint16_t)(v * 50 + 0.01))
#define PPS_A(a) ((uint8_t)(a * 20 + 0.01))
#define PD_PROTOCOL_MAX_NUM_OF_PDO 7
#define PD_PROTOCOL_EVENT_SRC_CAP (1 << 0)
#define PD_PROTOCOL_EVENT_PS_RDY (1 << 1)
#define PD_PROTOCOL_EVENT_ACCEPT (1 << 2)
#define PD_PROTOCOL_EVENT_REJECT (1 << 3)
#define PD_PROTOCOL_EVENT_PPS_STATUS (1 << 4)
typedef uint8_t PD_protocol_event_t;
enum PD_power_option_t {
PD_POWER_OPTION_MAX_5V = 0,
PD_POWER_OPTION_MAX_9V = 1,
PD_POWER_OPTION_MAX_12V = 2,
PD_POWER_OPTION_MAX_15V = 3,
PD_POWER_OPTION_MAX_20V = 4,
PD_POWER_OPTION_MAX_VOLTAGE = 5,
PD_POWER_OPTION_MAX_CURRENT = 6,
PD_POWER_OPTION_MAX_POWER = 7,
};
enum PD_power_data_obj_type_t { /* Power data object type */
PD_PDO_TYPE_FIXED_SUPPLY = 0,
PD_PDO_TYPE_BATTERY = 1,
PD_PDO_TYPE_VARIABLE_SUPPLY = 2,
PD_PDO_TYPE_AUGMENTED_PDO = 3 /* USB PD 3.0 */
};
enum PPS_PTF_t {
PPS_PTF_NOT_SUPPORT = 0,
PPS_PTF_NORMAL = 1,
PPS_PTF_WARNING = 2,
PPS_PTF_OVER_TEMPERATURE = 3
};
enum PPS_OMF_t {
PPS_OMF_VOLTAGE_MODE = 0,
PPS_OMF_CURRENT_LIMIT_MODE = 1
};
typedef struct {
uint16_t output_voltage; /* Voltage in 20mV units, 0xFFFF if not supported */
uint8_t output_current; /* Current in 50mV units, 0xFF if not supported */
enum PPS_PTF_t flag_PTF;
enum PPS_OMF_t flag_OMF;
} PPS_status_t;
typedef struct {
const char * name;
uint8_t id;
uint8_t spec_rev;
uint8_t num_of_obj;
uint8_t extended;
} PD_msg_info_t;
typedef struct {
enum PD_power_data_obj_type_t type;
uint16_t min_v; /* Voltage in 50mV units */
uint16_t max_v; /* Voltage in 50mV units */
uint16_t max_i; /* Current in 10mA units */
uint16_t max_p; /* Power in 250mW units */
} PD_power_info_t;
struct PD_msg_state_t;
typedef struct {
const struct PD_msg_state_t *msg_state;
uint16_t tx_msg_header;
uint16_t rx_msg_header;
uint8_t message_id;
uint16_t PPS_voltage;
uint8_t PPS_current;
uint8_t PPSSDB[4]; /* PPS Status Data Block */
enum PD_power_option_t power_option;
uint32_t power_data_obj[PD_PROTOCOL_MAX_NUM_OF_PDO];
uint8_t power_data_obj_count;
uint8_t power_data_obj_selected;
} PD_protocol_t;
/* Message handler */
void PD_protocol_handle_msg(PD_protocol_t *p, uint16_t header, uint32_t *obj, PD_protocol_event_t *events);
bool PD_protocol_respond(PD_protocol_t *p, uint16_t *h, uint32_t *obj);
/* PD Message creation */
void PD_protocol_create_get_src_cap(PD_protocol_t *p, uint16_t *header);
void PD_protocol_create_get_PPS_status(PD_protocol_t *p, uint16_t *header);
void PD_protocol_create_request(PD_protocol_t *p, uint16_t *header, uint32_t *obj);
/* Get functions */
static inline uint8_t PD_protocol_get_selected_power(PD_protocol_t *p) { return p->power_data_obj_selected; }
static inline uint16_t PD_protocol_get_PPS_voltage(PD_protocol_t *p) { return p->PPS_voltage; } /* Voltage in 20mV units */
static inline uint8_t PD_protocol_get_PPS_current(PD_protocol_t *p) { return p->PPS_current; } /* Current in 50mA units */
static inline uint16_t PD_protocol_get_tx_msg_header(PD_protocol_t *p) { return p->tx_msg_header; }
static inline uint16_t PD_protocol_get_rx_msg_header(PD_protocol_t *p) { return p->rx_msg_header; }
bool PD_protocol_get_msg_info(uint16_t header, PD_msg_info_t * msg_info);
bool PD_protocol_get_power_info(PD_protocol_t *p, uint8_t index, PD_power_info_t *power_info);
bool PD_protocol_get_PPS_status(PD_protocol_t *p, PPS_status_t * PPS_status);
/* Set Fixed and Variable power option */
bool PD_protocol_set_power_option(PD_protocol_t *p, enum PD_power_option_t option);
bool PD_protocol_select_power(PD_protocol_t *p, uint8_t index);
/* Set PPS Voltage in 20mV units, Current in 50mA units. return true if re-send request is needed
strict=true, If PPS setting is not qualified, return false, nothing is changed.
strict=false, if PPS setting is not qualified, fall back to regular power option */
bool PD_protocol_set_PPS(PD_protocol_t * p, uint16_t PPS_voltage, uint8_t PPS_current, bool strict);
void PD_protocol_reset(PD_protocol_t *p);
void PD_protocol_init(PD_protocol_t *p);
#endif

View File

@@ -1,196 +0,0 @@
#include "fusb302_dev.h"
#include "i2c.h"
#include "cmsis_os2.h"
#define FUSB302_USE_OS 1
#if FUSB302_USE_OS == 1
#define clock_ms() osKernelGetTickCount()
#define delay_ms(ms) osDelay(ms)
#else
#define clock_ms() HAL_GetTick()
#define delay_ms(ms) HAL_Delay(ms)
#endif
#define PD_POLLING 100
#define TYPEC_SINK_WAIT_CAP 350
#define REQUEST_TO_PS_READY 580
#define PPS_REQUEST 5000
FUSB302_dev_t fusb302_dev;
App_PD_t app_pd;
void fusb302_i2c_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t count)
{
HAL_I2C_Mem_Read(&hi2c1, dev_addr, reg_addr, I2C_MEMADD_SIZE_8BIT, data, count, 10);
}
void fusb302_i2c_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t count)
{
HAL_I2C_Mem_Write(&hi2c1, dev_addr, reg_addr, I2C_MEMADD_SIZE_8BIT, data, count, 10);
}
void status_power_ready(status_power_t status, uint16_t voltage, uint16_t current)
{
app_pd.ready_voltage = voltage;
app_pd.ready_current = current;
app_pd.status_power = status;
}
void set_default_power(void)
{
status_power_ready(STATUS_POWER_TYP, PD_V(5.0), PD_A(1.0));
}
void handle_protocol_event(PD_protocol_event_t events)
{
if (events & PD_PROTOCOL_EVENT_SRC_CAP) {
app_pd.wait_src_cap = 0;
app_pd.get_src_cap_retry_count = 0;
app_pd.wait_ps_rdy = 1;
app_pd.time_wait_ps_rdy = clock_ms();
app_pd.state = PD_STATE_GET_CAPS; // 更新状态:已收到能力,可以请求了
}
if (events & PD_PROTOCOL_EVENT_REJECT) {
if (app_pd.wait_ps_rdy) {
app_pd.wait_ps_rdy = 0;
app_pd.state = PD_STATE_FAILED; // 更新状态:请求被拒绝
}
}
if (events & PD_PROTOCOL_EVENT_PS_RDY) {
PD_power_info_t p;
uint8_t i, selected_power = PD_protocol_get_selected_power(&app_pd.protocol);
PD_protocol_get_power_info(&app_pd.protocol, selected_power, &p);
app_pd.wait_ps_rdy = 0;
if (p.type == PD_PDO_TYPE_AUGMENTED_PDO) {
// PPS mode
FUSB302_set_vbus_sense(&fusb302_dev, 0);
if (app_pd.PPS_voltage_next) {
// Two stage startup for PPS voltage < 5V
PD_protocol_set_PPS(&app_pd.protocol, app_pd.PPS_voltage_next, app_pd.PPS_current_next, false);
app_pd.PPS_voltage_next = 0;
app_pd.send_request = 1;
} else {
app_pd.time_PPS_request = clock_ms();
status_power_ready(STATUS_POWER_PPS,
PD_protocol_get_PPS_voltage(&app_pd.protocol), PD_protocol_get_PPS_current(&app_pd.protocol));
app_pd.state = PD_STATE_SUCCESS_PPS; // 更新状态成功协商到PPS
}
} else {
FUSB302_set_vbus_sense(&fusb302_dev, 1);
status_power_ready(STATUS_POWER_TYP, p.max_v, p.max_i);
app_pd.state = PD_STATE_SUCCESS_FIXED; // 更新状态:协商到了一个固定电压
}
}
}
void handle_FUSB302_event(FUSB302_event_t events)
{
if (events & FUSB302_EVENT_DETACHED) {
PD_protocol_reset(&app_pd.protocol);
app_pd.cc = 0;
return;
}
if (events & FUSB302_EVENT_ATTACHED) {
uint8_t cc1 = 0, cc2 = 0, cc = 0;
FUSB302_get_cc(&fusb302_dev, &cc1, &cc2);
PD_protocol_reset(&app_pd.protocol);
if (cc1 && cc2 == 0) {
cc = cc1;
app_pd.cc = 1;
} else if (cc2 && cc1 == 0) {
cc = cc2;
app_pd.cc = 2;
}
/* TODO: handle no cc detected error */
if (cc > 1) {
app_pd.wait_src_cap = 1;
} else {
set_default_power();
}
}
if (events & FUSB302_EVENT_RX_SOP) {
PD_protocol_event_t protocol_event = 0;
uint16_t header;
uint32_t obj[7];
FUSB302_get_message(&fusb302_dev, &header, obj);
PD_protocol_handle_msg(&app_pd.protocol, header, obj, &protocol_event);
if (protocol_event) {
handle_protocol_event(protocol_event);
}
}
if (events & FUSB302_EVENT_GOOD_CRC_SENT) {
uint16_t header;
uint32_t obj[7];
delay_ms(4); /* Delay respond in case there are retry messages */
if (PD_protocol_respond(&app_pd.protocol, &header, obj)) {
FUSB302_tx_sop(&fusb302_dev, header, obj);
}
}
}
bool fusb302_timer(void)
{
uint32_t t = clock_ms();
if (app_pd.wait_src_cap && t - app_pd.time_wait_src_cap > TYPEC_SINK_WAIT_CAP) {
app_pd.time_wait_src_cap = t;
if (app_pd.get_src_cap_retry_count < 3) {
uint16_t header;
app_pd.get_src_cap_retry_count += 1;
/* Try to request soruce capabilities message (will not cause power cycle VBUS) */
PD_protocol_create_get_src_cap(&app_pd.protocol, &header);
FUSB302_tx_sop(&fusb302_dev, header, 0);
} else {
app_pd.get_src_cap_retry_count = 0;
/* Hard reset will cause the source power cycle VBUS. */
FUSB302_tx_hard_reset(&fusb302_dev);
PD_protocol_reset(&app_pd.protocol);
}
}
if (app_pd.wait_ps_rdy) {
if (t - app_pd.time_wait_ps_rdy > REQUEST_TO_PS_READY) {
app_pd.wait_ps_rdy = 0;
set_default_power();
}
} else if (app_pd.send_request || (app_pd.status_power == STATUS_POWER_PPS && t - app_pd.time_PPS_request > PPS_REQUEST)) {
app_pd.wait_ps_rdy = 1;
app_pd.send_request = 0;
app_pd.state = PD_STATE_NEGOTIATING; // 更新状态:正在协商中
app_pd.time_PPS_request = t;
uint16_t header;
uint32_t obj[7];
/* Send request if option updated or regularly in PPS mode to keep power alive */
PD_protocol_create_request(&app_pd.protocol, &header, obj);
app_pd.time_wait_ps_rdy = clock_ms();
FUSB302_tx_sop(&fusb302_dev, header, obj);
}
if (t - app_pd.time_polling > PD_POLLING) {
app_pd.time_polling = t;
return true;
}
return false;
}
bool is_power_ready(void) { return app_pd.status_power == STATUS_POWER_TYP; }
bool is_PPS_ready(void) { return app_pd.status_power == STATUS_POWER_PPS; }
void send_power_request(void) { app_pd.send_request = 1; }
uint8_t fusb302_dev_init(void) {
fusb302_dev.i2c_address = 0x22<<1; // FUSB302 I2C address
fusb302_dev.i2c_read = fusb302_i2c_read;
fusb302_dev.i2c_write = fusb302_i2c_write;
#if FUSB302_USE_OS == 1
fusb302_dev.delay_ms = osDelay;
#else
fusb302_dev.delay_ms = HAL_Delay;
#endif
if (FUSB302_init(&fusb302_dev) == FUSB302_SUCCESS && FUSB302_get_ID(&fusb302_dev, 0, 0) == FUSB302_SUCCESS) {
PD_protocol_init(&app_pd.protocol);
app_pd.state = PD_STATE_IDLE; // 初始状态
return 0;
}
return 1;
}

View File

@@ -1,104 +0,0 @@
#ifndef __FUSB302_DEV_H__
#define __FUSB302_DEV_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "FUSB302_UFP.h"
#include "PD_UFP_Protocol.h"
typedef uint8_t status_power_t;
enum {
PD_UFP_VOLTAGE_LED_OFF = 0,
PD_UFP_VOLTAGE_LED_5V = 1,
PD_UFP_VOLTAGE_LED_9V = 2,
PD_UFP_VOLTAGE_LED_12V = 3,
PD_UFP_VOLTAGE_LED_15V = 4,
PD_UFP_VOLTAGE_LED_20V = 5,
PD_UFP_VOLTAGE_LED_AUTO = 6
};
typedef uint8_t PD_UFP_VOLTAGE_LED_t;
enum {
PD_UFP_CURRENT_LED_OFF = 0,
PD_UFP_CURRENT_LED_LE_1V = 1,
PD_UFP_CURRENT_LED_LE_3V = 2,
PD_UFP_CURRENT_LED_GT_3V = 3,
PD_UFP_CURRENT_LED_AUTO = 4
};
typedef uint8_t PD_UFP_CURRENT_LED_t;
enum {
STATUS_POWER_NA = 0,
STATUS_POWER_TYP,
STATUS_POWER_PPS
};
typedef uint8_t status_power_t;
enum {
PD_SYS_STATE_INIT = 0,
PD_SYS_STATE_READY,
PD_SYS_STATE_ERROR
};
typedef uint8_t PD_user_state_t;
typedef enum {
PD_STATE_IDLE, // 空闲状态
PD_STATE_NEGOTIATING, // 正在协商中 (已发送请求等待PS_RDY)
PD_STATE_SUCCESS_PPS, // 成功协商到PPS模式
PD_STATE_SUCCESS_FIXED, // 成功协商到固定电压
PD_STATE_FAILED, // 协商失败 (收到Reject或超时)
PD_STATE_GET_CAPS // 刚刚收到能力列表,准备发起第一次请求
} App_PD_State_t;
typedef struct
{
App_PD_State_t state;
PD_protocol_t protocol;
// Power ready power
uint16_t ready_voltage;
uint16_t ready_current;
// PPS setup
uint16_t PPS_voltage_next;
uint8_t PPS_current_next;
// Status
uint8_t status_initialized;
uint8_t status_src_cap_received;
status_power_t status_power;
// Timer and counter for PD Policy
uint32_t time_polling;
uint32_t time_wait_src_cap;
uint32_t time_wait_ps_rdy;
uint32_t time_PPS_request;
uint8_t get_src_cap_retry_count;
uint8_t wait_src_cap;
uint8_t wait_ps_rdy;
uint8_t send_request;
uint8_t cc;
char power_list[7][24];
uint8_t power_list_num;
uint8_t power_index;
float power_v;
float power_i;
}App_PD_t;
extern FUSB302_dev_t fusb302_dev;
extern App_PD_t app_pd;
uint8_t fusb302_dev_init(void);
void handle_FUSB302_event(FUSB302_event_t events);
bool is_power_ready(void);
bool is_PPS_ready(void);
void send_power_request(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,42 +0,0 @@
#ifndef __SYS_H__
#define __SYS_H__
#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"
#define OS_SUPPORT 1
#define SYS_CLK 100
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
typedef const int32_t sc32;
typedef const int16_t sc16;
typedef const int8_t sc8;
typedef __IO int32_t vs32;
typedef __IO int16_t vs16;
typedef __IO int8_t vs8;
typedef __I int32_t vsc32;
typedef __I int16_t vsc16;
typedef __I int8_t vsc8;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef const uint32_t uc32;
typedef const uint16_t uc16;
typedef const uint8_t uc8;
typedef __IO uint32_t vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t vu8;
typedef __I uint32_t vuc32;
typedef __I uint16_t vuc16;
typedef __I uint8_t vuc8;
#endif