feat✨: 添加显示服务
feat✨: 添加u8g2功能文件和移植文件
This commit is contained in:
parent
f77e70f144
commit
fcbba56bd2
@ -29,12 +29,14 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
#include "main_common.h"
|
#include "main_common.h"
|
||||||
#include "shell_port.h"
|
#include "shell_port.h"
|
||||||
|
|
||||||
#include "imp_msg_queue.h"
|
#include "imp_msg_queue.h"
|
||||||
#include "ext_trans_service.h"
|
#include "ext_trans_service.h"
|
||||||
|
#include "display_service.h"
|
||||||
|
|
||||||
/* define --------------------------------------------------------------------*/
|
/* define --------------------------------------------------------------------*/
|
||||||
/* typedef -------------------------------------------------------------------*/
|
/* typedef -------------------------------------------------------------------*/
|
||||||
@ -57,6 +59,7 @@ uint8_t _set_print_en(int argc, char** argv)
|
|||||||
|
|
||||||
uint8_t _set_send_msg_to(int argc, char** argv)
|
uint8_t _set_send_msg_to(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
// send id value
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
cdc_printf("too few argv: cmd sendtoid value_num\r\n");
|
cdc_printf("too few argv: cmd sendtoid value_num\r\n");
|
||||||
}
|
}
|
||||||
@ -76,11 +79,13 @@ uint8_t _main_task_wake_up_services()
|
|||||||
xTaskCreate(imp_ext_trans_service_task,
|
xTaskCreate(imp_ext_trans_service_task,
|
||||||
imp_main_task_table[IMP_TASK_ID_EXT_TRANS_SERVICE_TASK], 2048,
|
imp_main_task_table[IMP_TASK_ID_EXT_TRANS_SERVICE_TASK], 2048,
|
||||||
NULL, 10, NULL);
|
NULL, 10, NULL);
|
||||||
|
xTaskCreate(imp_display_service_task,
|
||||||
|
imp_main_task_table[IMP_TASK_ID_DISP_SERVICE_TASK], 2048, NULL,
|
||||||
|
11, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exported functions --------------------------------------------------------*/
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
void imp_main_app_task(void* param)
|
void imp_main_app_task(void* param)
|
||||||
{
|
{
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
@ -111,6 +116,7 @@ void imp_main_app_task(void * param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
|
ESP_LOGI("maint_task", "u8g2 init done");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,9 @@ idf_component_register(
|
|||||||
"components/msq_queue"
|
"components/msq_queue"
|
||||||
"components/imp_out_port"
|
"components/imp_out_port"
|
||||||
"services/ext_trans_service"
|
"services/ext_trans_service"
|
||||||
|
"utilities/u8g2/src"
|
||||||
|
"utilities/u8g2/port"
|
||||||
|
"services/display_service"
|
||||||
|
|
||||||
EXCLUDE_SRCS
|
EXCLUDE_SRCS
|
||||||
"utilities/usb_cherry/CherryUSB/class/cdc/usbh_cdc_acm.c"
|
"utilities/usb_cherry/CherryUSB/class/cdc/usbh_cdc_acm.c"
|
||||||
@ -43,8 +46,29 @@ idf_component_register(
|
|||||||
"components/imp_out_port"
|
"components/imp_out_port"
|
||||||
"services/ext_trans_service"
|
"services/ext_trans_service"
|
||||||
"utilities/imp_util_tlv_trans_protocol/"
|
"utilities/imp_util_tlv_trans_protocol/"
|
||||||
|
"utilities/u8g2/src"
|
||||||
|
"utilities/u8g2/port"
|
||||||
|
"services/display_service"
|
||||||
|
|
||||||
LDFRAGMENTS
|
LDFRAGMENTS
|
||||||
"utilities/letter_shell/port/esp-idf/shell.lf"
|
"utilities/letter_shell/port/esp-idf/shell.lf"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# 添加源文件
|
||||||
|
set(SOURCE_FILE_PATH
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/main.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/services/display_service/display_service.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/utilities/letter_shell/src/shell.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(ForceCompile
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "Forcing compilation of \"${SOURCE_FILE_PATH}\""
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${SOURCE_FILE_PATH}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||||
|
|
||||||
|
# 将可执行目标与自定义目标关联,以确保在每次构建时,ForceCompile 目标都会被执行
|
||||||
|
add_dependencies(${COMPONENT_LIB} ForceCompile)
|
||||||
@ -38,7 +38,8 @@ void app_main(void)
|
|||||||
{
|
{
|
||||||
_init_esp();
|
_init_esp();
|
||||||
vTaskDelay(10);
|
vTaskDelay(10);
|
||||||
imp_main_common_init();
|
int ret = imp_main_common_init();
|
||||||
|
ESP_LOGI("app_main", "main init finish %d \r\n", ret);
|
||||||
cdc_printf("Hello world!\r\n");
|
cdc_printf("Hello world!\r\n");
|
||||||
|
|
||||||
/* Print chip information */
|
/* Print chip information */
|
||||||
@ -77,7 +78,8 @@ void app_main(void)
|
|||||||
cdc_printf("start run app:\r\n");
|
cdc_printf("start run app:\r\n");
|
||||||
|
|
||||||
imp_msg_queue_init();
|
imp_msg_queue_init();
|
||||||
xTaskCreate(imp_main_app_task, "main", 2048, NULL, 10, NULL);
|
ESP_LOGI("app_main", "queue finish");
|
||||||
|
xTaskCreate(imp_main_app_task, "main", 2048, NULL, 20, NULL);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// cdc_printf("start run app:\r\n");
|
// cdc_printf("start run app:\r\n");
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
#include "shell_port.h"
|
#include "shell_port.h"
|
||||||
#include "main_app.h"
|
#include "main_app.h"
|
||||||
#include "imp_msg_queue.h"
|
#include "imp_msg_queue.h"
|
||||||
|
#include "esp_log.h"
|
||||||
#include "shell_port.h"
|
#include "shell_port.h"
|
||||||
/* define --------------------------------------------------------------------*/
|
/* define --------------------------------------------------------------------*/
|
||||||
/* typedef -------------------------------------------------------------------*/
|
/* typedef -------------------------------------------------------------------*/
|
||||||
@ -37,6 +38,7 @@ char* imp_main_task_table[] = {
|
|||||||
"idle",
|
"idle",
|
||||||
"main_task",
|
"main_task",
|
||||||
"ext_trans_task",
|
"ext_trans_task",
|
||||||
|
"display",
|
||||||
};
|
};
|
||||||
/* Private function(only *.c) -----------------------------------------------*/
|
/* Private function(only *.c) -----------------------------------------------*/
|
||||||
|
|
||||||
@ -66,13 +68,17 @@ uint8_t imp_main_common_init()
|
|||||||
{
|
{
|
||||||
cdc_acm_msc_init();
|
cdc_acm_msc_init();
|
||||||
imp_comp_out_port_init();
|
imp_comp_out_port_init();
|
||||||
|
ESP_LOGI("app_main", "imp_comp_out_port_init ok");
|
||||||
imp_comp_out_port_ioctl(EM_IMP_OUT_PORT_CMD_SET_OUT_READ_FUNC,
|
imp_comp_out_port_ioctl(EM_IMP_OUT_PORT_CMD_SET_OUT_READ_FUNC,
|
||||||
(uint8_t*)cdc_usb_read_bytes, 0);
|
(uint8_t*)cdc_usb_read_bytes, 0);
|
||||||
imp_comp_out_port_ioctl(EM_IMP_OUT_PORT_CMD_SET_OUT_WRIT_FUNC,
|
imp_comp_out_port_ioctl(EM_IMP_OUT_PORT_CMD_SET_OUT_WRIT_FUNC,
|
||||||
(uint8_t*)cdc_usb_writ_bytes, 0);
|
(uint8_t*)cdc_usb_writ_bytes, 0);
|
||||||
|
ESP_LOGI("app_main", "out port ok");
|
||||||
|
cdc_printf("out port ok\r\n");
|
||||||
vTaskDelay(10);
|
vTaskDelay(10);
|
||||||
userShellInit();
|
userShellInit();
|
||||||
vTaskDelay(10);
|
vTaskDelay(10);
|
||||||
|
cdc_printf("imp_main_common_init ok\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,7 @@ extern "C" {
|
|||||||
#define IMP_TASK_ID_IDLE (0)
|
#define IMP_TASK_ID_IDLE (0)
|
||||||
#define IMP_TASK_ID_MAIN_TASK (1)
|
#define IMP_TASK_ID_MAIN_TASK (1)
|
||||||
#define IMP_TASK_ID_EXT_TRANS_SERVICE_TASK (2)
|
#define IMP_TASK_ID_EXT_TRANS_SERVICE_TASK (2)
|
||||||
|
#define IMP_TASK_ID_DISP_SERVICE_TASK (3)
|
||||||
|
|
||||||
/* typedef -------------------------------------------------------------------*/
|
/* typedef -------------------------------------------------------------------*/
|
||||||
/* variables -----------------------------------------------------------------*/
|
/* variables -----------------------------------------------------------------*/
|
||||||
|
|||||||
82
main/services/display_service/display_service.c
Normal file
82
main/services/display_service/display_service.c
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* @file display_service.c
|
||||||
|
* @author Alvin Young (impressionyang@outlook.com)
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2025-03-20
|
||||||
|
*
|
||||||
|
* _ _
|
||||||
|
* (_)_ _ ___ _______ ___ ___ (_)__ ___ __ _____ ____ ___ _
|
||||||
|
* / / ' \/ _ \/ __/ -_|_-<(_-</ / _ \/ _ \/ // / _ `/ _ \/ _ `/
|
||||||
|
* /_/_/_/_/ .__/_/ \__/___/___/_/\___/_//_/\_, /\_,_/_//_/\_, /
|
||||||
|
* /_/ /___/ /___/
|
||||||
|
* @copyright Copyright (c) 2025 impressionyang
|
||||||
|
*
|
||||||
|
* @par 修改日志:
|
||||||
|
* <table>
|
||||||
|
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||||
|
* <tr><td>2025-03-20 <td>v1.0 <td>Alvin Young <td>首次创建
|
||||||
|
* </table>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "display_service.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "imp_msg_queue.h"
|
||||||
|
#include "main_common.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "u8g2.h"
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
/* define --------------------------------------------------------------------*/
|
||||||
|
/* typedef -------------------------------------------------------------------*/
|
||||||
|
/* variables -----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static imp_msg_queue_t* msg_q_handle = NULL;
|
||||||
|
static u8g2_t u8g2;
|
||||||
|
/* Private function(only *.c) -----------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
void imp_display_service_task(void*)
|
||||||
|
{
|
||||||
|
uint8_t msg_recv_ret = 0;
|
||||||
|
imp_msg_item_t msg_item = { 0 };
|
||||||
|
|
||||||
|
msg_q_handle = imp_msg_queue_create_handle(IMP_TASK_ID_DISP_SERVICE_TASK);
|
||||||
|
|
||||||
|
extern void u8g2Init(u8g2_t * u8g2);
|
||||||
|
u8g2Init(&u8g2);
|
||||||
|
|
||||||
|
char build_time[100] = {0};
|
||||||
|
snprintf(build_time, 100, "%s %s", __DATE__, __TIME__);
|
||||||
|
u8g2_SetFont(&u8g2, u8g2_font_helvB08_tr); // 设置英文字体
|
||||||
|
u8g2_DrawStr(&u8g2, 0, 13, "welcom to use u8g2");
|
||||||
|
u8g2_DrawStr(&u8g2, 0, 32, build_time);
|
||||||
|
u8g2_SendBuffer(&u8g2); // 一定要发送buffer
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
msg_recv_ret = imp_msg_queue_recv_msg(msg_q_handle, &msg_item, 10);
|
||||||
|
if (!msg_recv_ret) {
|
||||||
|
cdc_printf("%s get msg from %s OK\r\n", imp_main_task_table[msg_item.recv_id], imp_main_task_table[msg_item.send_id]);
|
||||||
|
switch (msg_item.msg_data) {
|
||||||
|
case 0:
|
||||||
|
// clear
|
||||||
|
u8g2_ClearBuffer(&u8g2);
|
||||||
|
u8g2_SendBuffer(&u8g2);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
u8g2_DrawStr(&u8g2, 0, 13, "impressionyang");
|
||||||
|
u8g2_SendBuffer(&u8g2); // 一定要发送buffer
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EOF
|
||||||
|
*/
|
||||||
0
main/services/display_service/display_service.c:
Normal file
0
main/services/display_service/display_service.c:
Normal file
48
main/services/display_service/display_service.h
Normal file
48
main/services/display_service/display_service.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* @file display_service.h
|
||||||
|
* @author Alvin Young (impressionyang@outlook.com)
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2025-03-20
|
||||||
|
*
|
||||||
|
* _ _
|
||||||
|
* (_)_ _ ___ _______ ___ ___ (_)__ ___ __ _____ ____ ___ _
|
||||||
|
* / / ' \/ _ \/ __/ -_|_-<(_-</ / _ \/ _ \/ // / _ `/ _ \/ _ `/
|
||||||
|
* /_/_/_/_/ .__/_/ \__/___/___/_/\___/_//_/\_, /\_,_/_//_/\_, /
|
||||||
|
* /_/ /___/ /___/
|
||||||
|
* @copyright Copyright (c) 2025 impressionyang
|
||||||
|
*
|
||||||
|
* @par 修改日志:
|
||||||
|
* <table>
|
||||||
|
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||||
|
* <tr><td>2025-03-20 <td>v1.0 <td>Alvin Young <td>首次创建
|
||||||
|
* </table>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __DISPLAY_SERVICE_H__
|
||||||
|
#define __DISPLAY_SERVICE_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "main_common.h"
|
||||||
|
/* define --------------------------------------------------------------------*/
|
||||||
|
/* typedef -------------------------------------------------------------------*/
|
||||||
|
/* variables -----------------------------------------------------------------*/
|
||||||
|
/* Private function(only *.c) -----------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
void imp_display_service_task(void *);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif//__DISPLAY_SERVICE_H__
|
||||||
|
/*
|
||||||
|
* EOF
|
||||||
|
*/
|
||||||
@ -94,8 +94,10 @@ void imp_ext_trans_service_task(void *)
|
|||||||
msg_read_ret = imp_msg_queue_recv_msg(msg_q_handle, &msg_item, 0);
|
msg_read_ret = imp_msg_queue_recv_msg(msg_q_handle, &msg_item, 0);
|
||||||
if (!msg_read_ret) {
|
if (!msg_read_ret) {
|
||||||
// read succeed
|
// read succeed
|
||||||
cdc_printf("read msg ok from %d to %d value: %d\r\n",
|
cdc_printf("%s get msg from %s value: %d\r\n",
|
||||||
msg_item.send_id, msg_item.recv_id, msg_item.msg_data);
|
imp_main_task_table[msg_item.recv_id],
|
||||||
|
imp_main_task_table[msg_item.send_id],
|
||||||
|
msg_item.msg_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// recv out
|
// recv out
|
||||||
|
|||||||
189
main/utilities/u8g2/port/imp_ug82_port.c
Normal file
189
main/utilities/u8g2/port/imp_ug82_port.c
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/**
|
||||||
|
* @file imp_ug82_port.c
|
||||||
|
* @author Alvin Young (impressionyang@outlook.com)
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2025-03-20
|
||||||
|
*
|
||||||
|
* _ _
|
||||||
|
* (_)_ _ ___ _______ ___ ___ (_)__ ___ __ _____ ____ ___ _
|
||||||
|
* / / ' \/ _ \/ __/ -_|_-<(_-</ / _ \/ _ \/ // / _ `/ _ \/ _ `/
|
||||||
|
* /_/_/_/_/ .__/_/ \__/___/___/_/\___/_//_/\_, /\_,_/_//_/\_, /
|
||||||
|
* /_/ /___/ /___/
|
||||||
|
* @copyright Copyright (c) 2025 impressionyang
|
||||||
|
*
|
||||||
|
* @par 修改日志:
|
||||||
|
* <table>
|
||||||
|
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||||
|
* <tr><td>2025-03-20 <td>v1.0 <td>Alvin Young <td>首次创建
|
||||||
|
* </table>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "driver/i2c.h"
|
||||||
|
#include "u8g2.h"
|
||||||
|
#include "u8x8.h"
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include "main_common.h"
|
||||||
|
/* define --------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/// @brief SCL pin
|
||||||
|
#define I2C_SCL_IO 34
|
||||||
|
/// @brief SDA pin
|
||||||
|
#define I2C_SDA_IO 33
|
||||||
|
/// @brief I2C master will check ack from slave
|
||||||
|
#define ACK_CHECK_EN 0x1
|
||||||
|
/// @brief I2C master write
|
||||||
|
#define WRITE_BIT I2C_MASTER_WRITE
|
||||||
|
|
||||||
|
/* typedef -------------------------------------------------------------------*/
|
||||||
|
/* variables -----------------------------------------------------------------*/
|
||||||
|
i2c_config_t i2c_config = {
|
||||||
|
.mode = I2C_MODE_MASTER, // set master mod
|
||||||
|
.sda_io_num = I2C_SDA_IO, // set sda pin
|
||||||
|
.scl_io_num = I2C_SCL_IO, // set scl pin
|
||||||
|
.sda_pullup_en = GPIO_PULLUP_ENABLE, // pull up mode
|
||||||
|
.scl_pullup_en = GPIO_PULLUP_ENABLE, // pull up mode
|
||||||
|
.master.clk_speed = 1000000 // set speed at 100KHz
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Private function(only *.c) -----------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* @date 2025-03-20
|
||||||
|
* @author Alvin Young (impressionyang@outlook.com)
|
||||||
|
*
|
||||||
|
* @details
|
||||||
|
* @note
|
||||||
|
* @par 修改日志:
|
||||||
|
* <table>
|
||||||
|
* <tr><th>Date <th>Author <th>Description
|
||||||
|
* <tr><td>2025-03-20 <td>Alvin Young <td>新建
|
||||||
|
* </table>
|
||||||
|
*/
|
||||||
|
static void _imp_i2c_ssd_oled_init(void)
|
||||||
|
{
|
||||||
|
i2c_param_config(I2C_NUM_0, &i2c_config);
|
||||||
|
i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* @param [in] addr
|
||||||
|
* @param [in] idx
|
||||||
|
* @param [in] data
|
||||||
|
* @date 2025-03-20
|
||||||
|
* @author Alvin Young (impressionyang@outlook.com)
|
||||||
|
*
|
||||||
|
* @details
|
||||||
|
* @note
|
||||||
|
* @par 修改日志:
|
||||||
|
* <table>
|
||||||
|
* <tr><th>Date <th>Author <th>Description
|
||||||
|
* <tr><td>2025-03-20 <td>Alvin Young <td>新建
|
||||||
|
* </table>
|
||||||
|
*/
|
||||||
|
void imp_i2c_ssd_oled_write(uint8_t addr, uint32_t idx, uint8_t* data)
|
||||||
|
{
|
||||||
|
i2c_cmd_handle_t handler = i2c_cmd_link_create();
|
||||||
|
i2c_master_start(handler);
|
||||||
|
i2c_master_write_byte(handler, addr | WRITE_BIT, ACK_CHECK_EN);
|
||||||
|
i2c_master_write(handler, data, idx, 2);
|
||||||
|
i2c_master_stop(handler);
|
||||||
|
i2c_master_cmd_begin(I2C_NUM_0, handler, pdMS_TO_TICKS(100));
|
||||||
|
i2c_cmd_link_delete(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* @param [in] u8x8
|
||||||
|
* @param [in] msg
|
||||||
|
* @param [in] arg_int
|
||||||
|
* @param [in] arg_ptr
|
||||||
|
* @return uint8_t
|
||||||
|
* @date 2025-03-20
|
||||||
|
* @author Alvin Young (impressionyang@outlook.com)
|
||||||
|
*
|
||||||
|
* @details
|
||||||
|
* @note
|
||||||
|
* @par 修改日志:
|
||||||
|
* <table>
|
||||||
|
* <tr><th>Date <th>Author <th>Description
|
||||||
|
* <tr><td>2025-03-20 <td>Alvin Young <td>新建
|
||||||
|
* </table>
|
||||||
|
*/
|
||||||
|
uint8_t imp_i2c_ssd_oled_8x8_gpio_delay(u8x8_t* u8x8, uint8_t msg,
|
||||||
|
uint8_t arg_int, void* arg_ptr)
|
||||||
|
{
|
||||||
|
switch (msg) {
|
||||||
|
case U8X8_MSG_GPIO_AND_DELAY_INIT:
|
||||||
|
_imp_i2c_ssd_oled_init(); //调用iic初始化
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DELAY_MILLI:
|
||||||
|
vTaskDelay(arg_int);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// u8g2用到的显示屏控制接口
|
||||||
|
uint8_t u8x8_byte_i2c(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr)
|
||||||
|
{
|
||||||
|
static uint8_t buffer
|
||||||
|
[32]; /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
|
||||||
|
static uint8_t buf_idx;
|
||||||
|
uint8_t* data;
|
||||||
|
// cdc_printf("i2c addr is 0x%02x\r\n", u8x8_GetI2CAddress(u8x8));
|
||||||
|
|
||||||
|
switch (msg) {
|
||||||
|
case U8X8_MSG_BYTE_SEND:
|
||||||
|
data = (uint8_t*)arg_ptr;
|
||||||
|
while (arg_int > 0) {
|
||||||
|
buffer[buf_idx++] = *data;
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_INIT:
|
||||||
|
/* add your custom code to init i2c subsystem */
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_SET_DC:
|
||||||
|
/* ignored for i2c */
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||||
|
buf_idx = 0;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||||
|
imp_i2c_ssd_oled_write(u8x8_GetI2CAddress(u8x8), buf_idx, buffer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2Init(u8g2_t* u8g2)
|
||||||
|
{
|
||||||
|
u8g2_Setup_ssd1306_i2c_128x64_noname_f(
|
||||||
|
u8g2, U8G2_R0, u8x8_byte_i2c,
|
||||||
|
imp_i2c_ssd_oled_8x8_gpio_delay); // 初始化 u8g2 结构体
|
||||||
|
u8g2_InitDisplay(
|
||||||
|
u8g2); // 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态
|
||||||
|
u8g2_SetPowerSave(u8g2, 0); // 打开显示器
|
||||||
|
u8g2_ClearBuffer(u8g2);
|
||||||
|
u8g2_SendBuffer(u8g2); // 清屏
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* EOF
|
||||||
|
*/
|
||||||
1004
main/utilities/u8g2/src/mui.c
Normal file
1004
main/utilities/u8g2/src/mui.c
Normal file
File diff suppressed because it is too large
Load Diff
614
main/utilities/u8g2/src/mui.h
Normal file
614
main/utilities/u8g2/src/mui.h
Normal file
@ -0,0 +1,614 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
mui.h
|
||||||
|
|
||||||
|
Monochrome minimal user interface: Core library.
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2021, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
MUIF (Monochrome User Interface Functions)
|
||||||
|
n: A number 0 to 9 without any quotes, e.g.: 5
|
||||||
|
id: Exactly two characters or numbers in double quotes, e.g. "G5".
|
||||||
|
cb: A callback function with the following prototype: "uint8_t muif_cb(mui_t *ui, uint8_t msg)"
|
||||||
|
There are MANY predefined callback functions, see separate list
|
||||||
|
var: Address of a variable.
|
||||||
|
text: Normal text, but special characters might be required for some callback functions, for
|
||||||
|
example the text might contain a list of selectable elements separated with the '|' symbol.
|
||||||
|
|
||||||
|
MUIF_STYLE(n,cb)
|
||||||
|
Corresponding FDS command: MUI_STYLE(n)
|
||||||
|
Change the style of any other elements after MUI_STYLE(n), does not draw anything
|
||||||
|
|
||||||
|
MUIF_RO(id,cb)
|
||||||
|
Corresponding FDS command: MUI_DATA(id, text) MUI_XY(id, x, y), MUI_XYT(id, x,y,text), MUI_XYA(id, x,y,a), MUI_XYAT(id, x,y,a,text)
|
||||||
|
Places a read only element on the form.
|
||||||
|
The correct FDS command depends on the callback function.
|
||||||
|
|
||||||
|
MUIF_LABEL(cb)
|
||||||
|
Corresponding FDS command: MUI_LABEL(x,y,text)
|
||||||
|
Places a text at the specified position, similar to MUIF_RO
|
||||||
|
|
||||||
|
MUIF_GOTO(cb)
|
||||||
|
Corresponding FDS command: MUI_GOTO(x,y,n,text)
|
||||||
|
Places a button at the specified position, similar to MUIF_BUTTON, but does not require an ID.
|
||||||
|
|
||||||
|
MUIF_BUTTON(id,cb)
|
||||||
|
Corresponding FDS command: MUI_XY(id, x, y), MUI_XYT(id, x,y,text), MUI_XYA(id, x,y,a), MUI_XYAT(id, x,y,a,text)
|
||||||
|
Places a selectable element on the form.
|
||||||
|
|
||||||
|
MUIF_VARIABLE(id,var,cb)
|
||||||
|
Corresponding FDS command: MUI_XY(id, x, y), MUI_XYA(id, x,y,a)
|
||||||
|
Places a user input element at the specified location.
|
||||||
|
The correct FDS command depends on the callback function.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MUI_H
|
||||||
|
#define MUI_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__AVR__)
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*==========================================*/
|
||||||
|
/* C++ compatible */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*==========================================*/
|
||||||
|
/* defines */
|
||||||
|
|
||||||
|
#define MUI_CHECK_EOFDS
|
||||||
|
|
||||||
|
|
||||||
|
/*==========================================*/
|
||||||
|
/* GNUC AVR PROGMEM interface */
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define MUI_NOINLINE __attribute__((noinline))
|
||||||
|
#else
|
||||||
|
# define MUI_NOINLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__AVR__)
|
||||||
|
# define mui_pgm_read(adr) pgm_read_byte_near(adr)
|
||||||
|
# define mui_pgm_wread(adr) pgm_read_word_near(adr)
|
||||||
|
# define MUI_PROGMEM PROGMEM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef mui_pgm_read
|
||||||
|
# ifndef CHAR_BIT
|
||||||
|
# define mui_pgm_read(adr) (*(const uint8_t *)(adr))
|
||||||
|
# else
|
||||||
|
# if CHAR_BIT > 8
|
||||||
|
# define mui_pgm_read(adr) ((*(const uint8_t *)(adr)) & 0x0ff)
|
||||||
|
# else
|
||||||
|
# define mui_pgm_read(adr) (*(const uint8_t *)(adr))
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef mui_pgm_wread
|
||||||
|
# define mui_pgm_wread(adr) (*(const uint16_t *)(adr))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MUI_PROGMEM
|
||||||
|
# define MUI_PROGMEM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*=== forward declarations ===*/
|
||||||
|
typedef struct mui_struct mui_t;
|
||||||
|
typedef const struct muif_struct muif_t;
|
||||||
|
typedef uint8_t (*muif_cb)(mui_t *ui, uint8_t msg);
|
||||||
|
typedef const char fds_t MUI_PROGMEM;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*=== struct declarations === */
|
||||||
|
|
||||||
|
struct muif_struct
|
||||||
|
{
|
||||||
|
uint8_t id0;
|
||||||
|
uint8_t id1;
|
||||||
|
uint8_t cflags; // config flags e.g. MUIF_CFLAG_IS_CURSOR_SELECTABLE, if so, then it will not receive any cursor/touch msgs
|
||||||
|
uint8_t extra;
|
||||||
|
void *data; // might be a pointer to a variable
|
||||||
|
muif_cb cb; // callback
|
||||||
|
} MUI_PROGMEM;
|
||||||
|
|
||||||
|
/* assumes that pointers are 16 bit so encapsulate the wread i another ifdef __AVR__ */
|
||||||
|
#if defined(__GNUC__) && defined(__AVR__)
|
||||||
|
# define muif_get_id0(muif) mui_pgm_read(&((muif)->id0))
|
||||||
|
# define muif_get_id1(muif) mui_pgm_read(&((muif)->id1))
|
||||||
|
# define muif_get_cflags(muif) mui_pgm_read(&((muif)->cflags))
|
||||||
|
# define muif_get_extra(muif) mui_pgm_read(&((muif)->extra))
|
||||||
|
# define muif_get_data(muif) ((void *)mui_pgm_wread(&((muif)->data)))
|
||||||
|
# define muif_get_cb(muif) ((muif_cb)mui_pgm_wread(&((muif)->cb)))
|
||||||
|
#else
|
||||||
|
# define muif_get_id0(muif) ((muif)->id0)
|
||||||
|
# define muif_get_id1(muif) ((muif)->id1)
|
||||||
|
# define muif_get_cflags(muif) ((muif)->cflags)
|
||||||
|
# define muif_get_extra(muif) ((muif)->extra)
|
||||||
|
# define muif_get_data(muif) ((muif)->data)
|
||||||
|
# define muif_get_cb(muif) ((muif)->cb)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define MUIF_MSG_NONE 0
|
||||||
|
#define MUIF_MSG_DRAW 1
|
||||||
|
#define MUIF_MSG_FORM_START 2
|
||||||
|
#define MUIF_MSG_FORM_END 3
|
||||||
|
/* MUIF_MSG_CURSOR_ENTER return values: 255=skip this field, <255, continue*/
|
||||||
|
#define MUIF_MSG_CURSOR_ENTER 4
|
||||||
|
#define MUIF_MSG_CURSOR_SELECT 5
|
||||||
|
|
||||||
|
/* optional VALUE messages, ignored by the mui core, but can be used inside the field functions */
|
||||||
|
/* usually MUIF_MSG_VALUE_INCREMENT behaves like MUIF_MSG_CURSOR_SELECT */
|
||||||
|
#define MUIF_MSG_VALUE_INCREMENT 6
|
||||||
|
#define MUIF_MSG_VALUE_DECREMENT 7
|
||||||
|
|
||||||
|
|
||||||
|
#define MUIF_MSG_CURSOR_LEAVE 8
|
||||||
|
#define MUIF_MSG_TOUCH_DOWN 9
|
||||||
|
#define MUIF_MSG_TOUCH_UP 10
|
||||||
|
/* MUIF_MSG_EVENT_NEXT return values: 0=not handled, 1=handled, do nothing */
|
||||||
|
/* If MUIF_MSG_EVENT_NEXT/PREV are NOT handled by the field function, then this msg will change the field */
|
||||||
|
#define MUIF_MSG_EVENT_NEXT 11
|
||||||
|
/* MUIF_MSG_EVENT_PREV return values: 0=not handled, 1=handled, do nothing */
|
||||||
|
#define MUIF_MSG_EVENT_PREV 12
|
||||||
|
|
||||||
|
/* dynamic flags */
|
||||||
|
#define MUIF_DFLAG_IS_CURSOR_FOCUS 0x01
|
||||||
|
#define MUIF_DFLAG_IS_TOUCH_FOCUS 0x02
|
||||||
|
|
||||||
|
/* config flags */
|
||||||
|
#define MUIF_CFLAG_IS_CURSOR_SELECTABLE 0x01
|
||||||
|
#define MUIF_CFLAG_IS_TOUCH_SELECTABLE 0x02
|
||||||
|
#define MUIF_CFLAG_IS_EXECUTE_ON_SELECT 0x04
|
||||||
|
|
||||||
|
|
||||||
|
/* end user MUIF entries */
|
||||||
|
#define MUIF(id,cflags,data,cb) { id[0], id[1], cflags, 0, data, cb}
|
||||||
|
#define MUIF_STYLE(n,cb) MUIF("S" #n, 0, 0, cb)
|
||||||
|
#define MUIF_RO(id,cb) MUIF(id,0, 0,cb)
|
||||||
|
#define MUIF_LABEL(cb) MUIF(".L",0, 0,cb)
|
||||||
|
#define MUIF_GOTO(cb) MUIF(".G",MUIF_CFLAG_IS_CURSOR_SELECTABLE,0,cb)
|
||||||
|
#define MUIF_BUTTON(id,cb) MUIF(id,MUIF_CFLAG_IS_CURSOR_SELECTABLE,0,cb)
|
||||||
|
#define MUIF_EXECUTE_ON_SELECT_BUTTON(id,cb) MUIF(id,MUIF_CFLAG_IS_CURSOR_SELECTABLE|MUIF_CFLAG_IS_EXECUTE_ON_SELECT,0,cb)
|
||||||
|
#define MUIF_VARIABLE(id,var,cb) MUIF(id,MUIF_CFLAG_IS_CURSOR_SELECTABLE,(var),cb)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* must be smaller than or equal to 255 */
|
||||||
|
#ifndef MUI_MAX_TEXT_LEN
|
||||||
|
#define MUI_MAX_TEXT_LEN 41
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MUI_MENU_CACHE_CNT 4
|
||||||
|
|
||||||
|
#define MUI_MENU_LAST_FORM_STACK_SIZE 4
|
||||||
|
|
||||||
|
struct mui_struct
|
||||||
|
{
|
||||||
|
void *graphics_data;
|
||||||
|
fds_t *root_fds;
|
||||||
|
|
||||||
|
muif_t *muif_tlist;
|
||||||
|
size_t muif_tcnt;
|
||||||
|
|
||||||
|
fds_t *current_form_fds; // the current form, NULL if the ui is not active at the moment
|
||||||
|
fds_t *cursor_focus_fds; // the field which has the current cursor focus, NULL if there is no current focus
|
||||||
|
fds_t *touch_focus_fds; // the field which has touch focus
|
||||||
|
|
||||||
|
fds_t *token; // current token position
|
||||||
|
|
||||||
|
uint16_t form_scroll_total; // reserved for MUIF, not used by mui
|
||||||
|
uint16_t form_scroll_top; // reserved for MUIF, not used by mui
|
||||||
|
uint8_t form_scroll_visible; // reserved for MUIF, not used by mui
|
||||||
|
|
||||||
|
|
||||||
|
//uint8_t selected_value; // This variable is not used by the user interface but can be used by any field function
|
||||||
|
uint8_t tmp8;
|
||||||
|
|
||||||
|
/* 0: mse, 1: mud */
|
||||||
|
uint8_t is_mud; // a temp variable for the MUIF function to store remember up down mode. This variable will be cleared before sending MUIF_MSG_CURSOR_ENTER
|
||||||
|
/* current field/style variables */
|
||||||
|
//uint8_t cursor_focus_position; // the index of the field which has focus, can be used as last argument for mui_EnterForm
|
||||||
|
|
||||||
|
uint8_t delimiter; // outer delimiter of the text part of a field
|
||||||
|
uint8_t cmd; // current cmd or field (e.g. U or F)
|
||||||
|
uint8_t id0; // identifier of the field, manually provided or derived (G cmd has fixed id "FG")
|
||||||
|
uint8_t id1;
|
||||||
|
uint8_t x; // position of the field
|
||||||
|
uint8_t y;
|
||||||
|
uint8_t dflags;
|
||||||
|
uint8_t arg; // extra argument of the field. For example the G: form is put here
|
||||||
|
int len; // length of the current command
|
||||||
|
fds_t *fds; // current position, *fds = cmd
|
||||||
|
muif_t *uif; // user interface field or style for the given id0 / id1, assigned by mui_prepare_current_field()
|
||||||
|
char text[MUI_MAX_TEXT_LEN+1];
|
||||||
|
|
||||||
|
/* target */
|
||||||
|
fds_t *tmp_fds;
|
||||||
|
fds_t *target_fds; // used by several task functions as a return / result value
|
||||||
|
|
||||||
|
/* last form and field, used by mui_SaveForm and mui_RestoreForm */
|
||||||
|
uint8_t last_form_id[MUI_MENU_LAST_FORM_STACK_SIZE];
|
||||||
|
uint8_t last_form_cursor_focus_position[MUI_MENU_LAST_FORM_STACK_SIZE];
|
||||||
|
fds_t *last_form_fds; // not used by mui_RestoreForm, but can be used by field functions, warning: this is the FDS of the field, from where the jump started to the child (cursor_focus_fds)
|
||||||
|
int8_t last_form_stack_pos;
|
||||||
|
|
||||||
|
/* menu cursor position backup */
|
||||||
|
/* idea is, to restore the cursor position if we jump to that form */
|
||||||
|
uint8_t menu_form_last_added;
|
||||||
|
uint8_t menu_form_id[MUI_MENU_CACHE_CNT];
|
||||||
|
uint8_t menu_form_cursor_focus_position[MUI_MENU_CACHE_CNT];
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#define mui_IsCursorFocus(mui) ((mui)->dflags & MUIF_DFLAG_IS_CURSOR_FOCUS)
|
||||||
|
#define mui_IsTouchFocus(mui) ((mui)->dflags & MUIF_CFLAG_IS_TOUCH_SELECTABLE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*=== form string definitions ===*/
|
||||||
|
|
||||||
|
#define MUI_0 "\x00"
|
||||||
|
#define MUI_1 "\x01"
|
||||||
|
#define MUI_2 "\x02"
|
||||||
|
#define MUI_3 "\x03"
|
||||||
|
#define MUI_4 "\x04"
|
||||||
|
#define MUI_5 "\x05"
|
||||||
|
#define MUI_6 "\x06"
|
||||||
|
#define MUI_7 "\x07"
|
||||||
|
#define MUI_8 "\x08"
|
||||||
|
#define MUI_9 "\x09"
|
||||||
|
#define MUI_10 "\x0a"
|
||||||
|
#define MUI_11 "\x0b"
|
||||||
|
#define MUI_12 "\x0c"
|
||||||
|
#define MUI_13 "\x0d"
|
||||||
|
#define MUI_14 "\x0e"
|
||||||
|
#define MUI_15 "\x0f"
|
||||||
|
#define MUI_16 "\x10"
|
||||||
|
#define MUI_17 "\x11"
|
||||||
|
#define MUI_18 "\x12"
|
||||||
|
#define MUI_19 "\x13"
|
||||||
|
#define MUI_20 "\x14"
|
||||||
|
#define MUI_21 "\x15"
|
||||||
|
#define MUI_22 "\x16"
|
||||||
|
#define MUI_23 "\x17"
|
||||||
|
#define MUI_24 "\x18"
|
||||||
|
#define MUI_25 "\x19"
|
||||||
|
#define MUI_26 "\x1a"
|
||||||
|
#define MUI_27 "\x1b"
|
||||||
|
#define MUI_28 "\x1c"
|
||||||
|
#define MUI_29 "\x1d"
|
||||||
|
#define MUI_30 "\x1e"
|
||||||
|
#define MUI_31 "\x1f"
|
||||||
|
#define MUI_32 "\x20"
|
||||||
|
#define MUI_33 "\x21"
|
||||||
|
#define MUI_34 "\x22"
|
||||||
|
#define MUI_35 "\x23"
|
||||||
|
#define MUI_36 "\x24"
|
||||||
|
#define MUI_37 "\x25"
|
||||||
|
#define MUI_38 "\x26"
|
||||||
|
#define MUI_39 "\x27"
|
||||||
|
#define MUI_40 "\x28"
|
||||||
|
#define MUI_41 "\x29"
|
||||||
|
#define MUI_42 "\x2a"
|
||||||
|
#define MUI_43 "\x2b"
|
||||||
|
#define MUI_44 "\x2c"
|
||||||
|
#define MUI_45 "\x2d"
|
||||||
|
#define MUI_46 "\x2e"
|
||||||
|
#define MUI_47 "\x2f"
|
||||||
|
#define MUI_48 "\x30"
|
||||||
|
#define MUI_49 "\x31"
|
||||||
|
#define MUI_50 "\x32"
|
||||||
|
#define MUI_51 "\x33"
|
||||||
|
#define MUI_52 "\x34"
|
||||||
|
#define MUI_53 "\x35"
|
||||||
|
#define MUI_54 "\x36"
|
||||||
|
#define MUI_55 "\x37"
|
||||||
|
#define MUI_56 "\x38"
|
||||||
|
#define MUI_57 "\x39"
|
||||||
|
#define MUI_58 "\x3a"
|
||||||
|
#define MUI_59 "\x3b"
|
||||||
|
#define MUI_60 "\x3c"
|
||||||
|
#define MUI_61 "\x3d"
|
||||||
|
#define MUI_62 "\x3e"
|
||||||
|
#define MUI_63 "\x3f"
|
||||||
|
#define MUI_64 "\x40"
|
||||||
|
#define MUI_65 "\x41"
|
||||||
|
#define MUI_66 "\x42"
|
||||||
|
#define MUI_67 "\x43"
|
||||||
|
#define MUI_68 "\x44"
|
||||||
|
#define MUI_69 "\x45"
|
||||||
|
#define MUI_70 "\x46"
|
||||||
|
#define MUI_71 "\x47"
|
||||||
|
#define MUI_72 "\x48"
|
||||||
|
#define MUI_73 "\x49"
|
||||||
|
#define MUI_74 "\x4a"
|
||||||
|
#define MUI_75 "\x4b"
|
||||||
|
#define MUI_76 "\x4c"
|
||||||
|
#define MUI_77 "\x4d"
|
||||||
|
#define MUI_78 "\x4e"
|
||||||
|
#define MUI_79 "\x4f"
|
||||||
|
#define MUI_80 "\x50"
|
||||||
|
#define MUI_81 "\x51"
|
||||||
|
#define MUI_82 "\x52"
|
||||||
|
#define MUI_83 "\x53"
|
||||||
|
#define MUI_84 "\x54"
|
||||||
|
#define MUI_85 "\x55"
|
||||||
|
#define MUI_86 "\x56"
|
||||||
|
#define MUI_87 "\x57"
|
||||||
|
#define MUI_88 "\x58"
|
||||||
|
#define MUI_89 "\x59"
|
||||||
|
#define MUI_90 "\x5a"
|
||||||
|
#define MUI_91 "\x5b"
|
||||||
|
#define MUI_92 "\x5c"
|
||||||
|
#define MUI_93 "\x5d"
|
||||||
|
#define MUI_94 "\x5e"
|
||||||
|
#define MUI_95 "\x5f"
|
||||||
|
#define MUI_96 "\x60"
|
||||||
|
#define MUI_97 "\x61"
|
||||||
|
#define MUI_98 "\x62"
|
||||||
|
#define MUI_99 "\x63"
|
||||||
|
#define MUI_100 "\x64"
|
||||||
|
#define MUI_101 "\x65"
|
||||||
|
#define MUI_102 "\x66"
|
||||||
|
#define MUI_103 "\x67"
|
||||||
|
#define MUI_104 "\x68"
|
||||||
|
#define MUI_105 "\x69"
|
||||||
|
#define MUI_106 "\x6a"
|
||||||
|
#define MUI_107 "\x6b"
|
||||||
|
#define MUI_108 "\x6c"
|
||||||
|
#define MUI_109 "\x6d"
|
||||||
|
#define MUI_110 "\x6e"
|
||||||
|
#define MUI_111 "\x6f"
|
||||||
|
#define MUI_112 "\x70"
|
||||||
|
#define MUI_113 "\x71"
|
||||||
|
#define MUI_114 "\x72"
|
||||||
|
#define MUI_115 "\x73"
|
||||||
|
#define MUI_116 "\x74"
|
||||||
|
#define MUI_117 "\x75"
|
||||||
|
#define MUI_118 "\x76"
|
||||||
|
#define MUI_119 "\x77"
|
||||||
|
#define MUI_120 "\x78"
|
||||||
|
#define MUI_121 "\x79"
|
||||||
|
#define MUI_122 "\x7a"
|
||||||
|
#define MUI_123 "\x7b"
|
||||||
|
#define MUI_124 "\x7c"
|
||||||
|
#define MUI_125 "\x7d"
|
||||||
|
#define MUI_126 "\x7e"
|
||||||
|
#define MUI_127 "\x7f"
|
||||||
|
#define MUI_128 "\x80"
|
||||||
|
#define MUI_129 "\x81"
|
||||||
|
#define MUI_130 "\x82"
|
||||||
|
#define MUI_131 "\x83"
|
||||||
|
#define MUI_132 "\x84"
|
||||||
|
#define MUI_133 "\x85"
|
||||||
|
#define MUI_134 "\x86"
|
||||||
|
#define MUI_135 "\x87"
|
||||||
|
#define MUI_136 "\x88"
|
||||||
|
#define MUI_137 "\x89"
|
||||||
|
#define MUI_138 "\x8a"
|
||||||
|
#define MUI_139 "\x8b"
|
||||||
|
#define MUI_140 "\x8c"
|
||||||
|
#define MUI_141 "\x8d"
|
||||||
|
#define MUI_142 "\x8e"
|
||||||
|
#define MUI_143 "\x8f"
|
||||||
|
#define MUI_144 "\x90"
|
||||||
|
#define MUI_145 "\x91"
|
||||||
|
#define MUI_146 "\x92"
|
||||||
|
#define MUI_147 "\x93"
|
||||||
|
#define MUI_148 "\x94"
|
||||||
|
#define MUI_149 "\x95"
|
||||||
|
#define MUI_150 "\x96"
|
||||||
|
#define MUI_151 "\x97"
|
||||||
|
#define MUI_152 "\x98"
|
||||||
|
#define MUI_153 "\x99"
|
||||||
|
#define MUI_154 "\x9a"
|
||||||
|
#define MUI_155 "\x9b"
|
||||||
|
#define MUI_156 "\x9c"
|
||||||
|
#define MUI_157 "\x9d"
|
||||||
|
#define MUI_158 "\x9e"
|
||||||
|
#define MUI_159 "\x9f"
|
||||||
|
#define MUI_160 "\xa0"
|
||||||
|
#define MUI_161 "\xa1"
|
||||||
|
#define MUI_162 "\xa2"
|
||||||
|
#define MUI_163 "\xa3"
|
||||||
|
#define MUI_164 "\xa4"
|
||||||
|
#define MUI_165 "\xa5"
|
||||||
|
#define MUI_166 "\xa6"
|
||||||
|
#define MUI_167 "\xa7"
|
||||||
|
#define MUI_168 "\xa8"
|
||||||
|
#define MUI_169 "\xa9"
|
||||||
|
#define MUI_170 "\xaa"
|
||||||
|
#define MUI_171 "\xab"
|
||||||
|
#define MUI_172 "\xac"
|
||||||
|
#define MUI_173 "\xad"
|
||||||
|
#define MUI_174 "\xae"
|
||||||
|
#define MUI_175 "\xaf"
|
||||||
|
#define MUI_176 "\xb0"
|
||||||
|
#define MUI_177 "\xb1"
|
||||||
|
#define MUI_178 "\xb2"
|
||||||
|
#define MUI_179 "\xb3"
|
||||||
|
#define MUI_180 "\xb4"
|
||||||
|
#define MUI_181 "\xb5"
|
||||||
|
#define MUI_182 "\xb6"
|
||||||
|
#define MUI_183 "\xb7"
|
||||||
|
#define MUI_184 "\xb8"
|
||||||
|
#define MUI_185 "\xb9"
|
||||||
|
#define MUI_186 "\xba"
|
||||||
|
#define MUI_187 "\xbb"
|
||||||
|
#define MUI_188 "\xbc"
|
||||||
|
#define MUI_189 "\xbd"
|
||||||
|
#define MUI_190 "\xbe"
|
||||||
|
#define MUI_191 "\xbf"
|
||||||
|
#define MUI_192 "\xc0"
|
||||||
|
#define MUI_193 "\xc1"
|
||||||
|
#define MUI_194 "\xc2"
|
||||||
|
#define MUI_195 "\xc3"
|
||||||
|
#define MUI_196 "\xc4"
|
||||||
|
#define MUI_197 "\xc5"
|
||||||
|
#define MUI_198 "\xc6"
|
||||||
|
#define MUI_199 "\xc7"
|
||||||
|
#define MUI_200 "\xc8"
|
||||||
|
#define MUI_201 "\xc9"
|
||||||
|
#define MUI_202 "\xca"
|
||||||
|
#define MUI_203 "\xcb"
|
||||||
|
#define MUI_204 "\xcc"
|
||||||
|
#define MUI_205 "\xcd"
|
||||||
|
#define MUI_206 "\xce"
|
||||||
|
#define MUI_207 "\xcf"
|
||||||
|
#define MUI_208 "\xd0"
|
||||||
|
#define MUI_209 "\xd1"
|
||||||
|
#define MUI_210 "\xd2"
|
||||||
|
#define MUI_211 "\xd3"
|
||||||
|
#define MUI_212 "\xd4"
|
||||||
|
#define MUI_213 "\xd5"
|
||||||
|
#define MUI_214 "\xd6"
|
||||||
|
#define MUI_215 "\xd7"
|
||||||
|
#define MUI_216 "\xd8"
|
||||||
|
#define MUI_217 "\xd9"
|
||||||
|
#define MUI_218 "\xda"
|
||||||
|
#define MUI_219 "\xdb"
|
||||||
|
#define MUI_220 "\xdc"
|
||||||
|
#define MUI_221 "\xdd"
|
||||||
|
#define MUI_222 "\xde"
|
||||||
|
#define MUI_223 "\xdf"
|
||||||
|
#define MUI_224 "\xe0"
|
||||||
|
#define MUI_225 "\xe1"
|
||||||
|
#define MUI_226 "\xe2"
|
||||||
|
#define MUI_227 "\xe3"
|
||||||
|
#define MUI_228 "\xe4"
|
||||||
|
#define MUI_229 "\xe5"
|
||||||
|
#define MUI_230 "\xe6"
|
||||||
|
#define MUI_231 "\xe7"
|
||||||
|
#define MUI_232 "\xe8"
|
||||||
|
#define MUI_233 "\xe9"
|
||||||
|
#define MUI_234 "\xea"
|
||||||
|
#define MUI_235 "\xeb"
|
||||||
|
#define MUI_236 "\xec"
|
||||||
|
#define MUI_237 "\xed"
|
||||||
|
#define MUI_238 "\xee"
|
||||||
|
#define MUI_239 "\xef"
|
||||||
|
#define MUI_240 "\xf0"
|
||||||
|
#define MUI_241 "\xf1"
|
||||||
|
#define MUI_242 "\xf2"
|
||||||
|
#define MUI_243 "\xf3"
|
||||||
|
#define MUI_244 "\xf4"
|
||||||
|
#define MUI_245 "\xf5"
|
||||||
|
#define MUI_246 "\xf6"
|
||||||
|
#define MUI_247 "\xf7"
|
||||||
|
#define MUI_248 "\xf8"
|
||||||
|
#define MUI_249 "\xf9"
|
||||||
|
#define MUI_250 "\xfa"
|
||||||
|
#define MUI_251 "\xfb"
|
||||||
|
#define MUI_252 "\xfc"
|
||||||
|
#define MUI_253 "\xfd"
|
||||||
|
#define MUI_254 "\xfe"
|
||||||
|
#define MUI_255 "\xff"
|
||||||
|
|
||||||
|
/* form: one id only */
|
||||||
|
#define MUI_FORM(n) "U" MUI_##n
|
||||||
|
|
||||||
|
/* style: one id only */
|
||||||
|
#define MUI_STYLE(n) "S" #n
|
||||||
|
|
||||||
|
#define MUI_AUX(id) "Z" id
|
||||||
|
|
||||||
|
#define MUI_DATA(id, text) "D" id "\xff" text "\xff"
|
||||||
|
|
||||||
|
#define MUI_XY(id, x, y) "F" id MUI_##x MUI_##y
|
||||||
|
/* button id must be two chars, but must be unique everywhere */
|
||||||
|
#define MUI_XYT(id, x,y,text) "B" id MUI_##x MUI_##y "\xff" text "\xff"
|
||||||
|
#define MUI_XYA(id, x,y,a) "A" id MUI_##x MUI_##y MUI_##a
|
||||||
|
#define MUI_XYAT(id, x,y,a,text) "T" id MUI_##x MUI_##y MUI_##a "\xff" text "\xff"
|
||||||
|
|
||||||
|
#define MUI_LABEL(x,y,text) "L" MUI_##x MUI_##y "\xff" text "\xff"
|
||||||
|
#define MUI_GOTO(x,y,n,text) "G" MUI_##x MUI_##y MUI_##n "\xff" text "\xff"
|
||||||
|
#define MUI_goto(x,y,n,text) "g" MUI_##x MUI_##y MUI_##n "\xff" text "\xff"
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t mui_get_fds_char(fds_t *s) MUI_NOINLINE;
|
||||||
|
|
||||||
|
uint8_t mui_fds_first_token(mui_t *ui) MUI_NOINLINE;
|
||||||
|
uint8_t mui_fds_next_token(mui_t *ui) MUI_NOINLINE;
|
||||||
|
uint8_t mui_fds_get_nth_token(mui_t *ui, uint8_t n) MUI_NOINLINE;
|
||||||
|
uint8_t mui_fds_get_token_cnt(mui_t *ui) MUI_NOINLINE;
|
||||||
|
|
||||||
|
void mui_Init(mui_t *ui, void *graphics_data, fds_t *fds, muif_t *muif_tlist, size_t muif_tcnt);
|
||||||
|
uint8_t mui_GetCurrentCursorFocusPosition(mui_t *ui) ;
|
||||||
|
void mui_Draw(mui_t *ui);
|
||||||
|
/* warning: The next function will overwrite the ui field variables like ui->arg, etc. 26 sep 2021: only ui->text is modified */
|
||||||
|
uint8_t mui_GetSelectableFieldTextOption(mui_t *ui, fds_t *fds, uint8_t nth_token);
|
||||||
|
/* warning: The next function will overwrite the ui field variables like ui->arg, etc 26 sep 2021: only ui->text is modified*/
|
||||||
|
uint8_t mui_GetSelectableFieldOptionCnt(mui_t *ui, fds_t *fds);
|
||||||
|
void mui_EnterForm(mui_t *ui, fds_t *fds, uint8_t initial_cursor_position);
|
||||||
|
void mui_LeaveForm(mui_t *ui);
|
||||||
|
uint8_t mui_GotoForm(mui_t *ui, uint8_t form_id, uint8_t initial_cursor_position);
|
||||||
|
void mui_SaveFormWithCursorPosition(mui_t *ui, uint8_t cursor_pos); /* Save current form with manully provied cursor position, Used together with mui_RestoreForm */
|
||||||
|
void mui_SaveForm(mui_t *ui); /* Save current form+cursor position. Used together with mui_RestoreForm */
|
||||||
|
uint8_t mui_RestoreForm(mui_t *ui); /* Restore form and cursor position, previously saved with mui_SaveForm */
|
||||||
|
void mui_SaveCursorPosition(mui_t *ui, uint8_t cursor_position); /* stores a cursor position for use with mui_GotoFormAutoCursorPosition */
|
||||||
|
uint8_t mui_GotoFormAutoCursorPosition(mui_t *ui, uint8_t form_id);
|
||||||
|
|
||||||
|
int mui_GetCurrentFormId(mui_t *ui); /* form id or -1 if the menu system is inactive */
|
||||||
|
void mui_NextField(mui_t *ui);
|
||||||
|
void mui_PrevField(mui_t *ui);
|
||||||
|
void mui_SendSelect(mui_t *ui);
|
||||||
|
void mui_SendSelectWithExecuteOnSelectFieldSearch(mui_t *ui); /* use this if MUIF_EXECUTE_ON_SELECT_BUTTON is used */
|
||||||
|
|
||||||
|
void mui_SendValueIncrement(mui_t *ui);
|
||||||
|
void mui_SendValueDecrement(mui_t *ui);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define mui_IsFormActive(ui) ((ui)->current_form_fds != NULL)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MUI_H */
|
||||||
|
|
||||||
2678
main/utilities/u8g2/src/mui_u8g2.c
Normal file
2678
main/utilities/u8g2/src/mui_u8g2.c
Normal file
File diff suppressed because it is too large
Load Diff
350
main/utilities/u8g2/src/mui_u8g2.h
Normal file
350
main/utilities/u8g2/src/mui_u8g2.h
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
mui_u8g2.h
|
||||||
|
|
||||||
|
Monochrome minimal user interface: Glue code between mui and u8g2.
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2021, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
Reference Manual:
|
||||||
|
https://github.com/olikraus/u8g2/wiki/muiref
|
||||||
|
|
||||||
|
MUIF_U8G2_LABEL()
|
||||||
|
replacement for MUIF_LABEL(mui_u8g2_draw_text),
|
||||||
|
used by MUI_LABEL(x,y,"text")
|
||||||
|
Supports UTF8
|
||||||
|
|
||||||
|
MUIF_U8G2_FONT_STYLE(n, font)
|
||||||
|
A special u8g2 style function, which replaces MUIF_STYLE, but restricts the style change to the
|
||||||
|
specific font argument (however, this should be good enough in most cases).
|
||||||
|
As usual, the style "n" can be activated with MUI_STYLE(n) in FDS.
|
||||||
|
Example:
|
||||||
|
muif_t muif_list[] MUI_PROGMEM = {
|
||||||
|
MUIF_U8G2_LABEL(),
|
||||||
|
MUIF_U8G2_FONT_STYLE(0, u8g2_font_5x8_tr)
|
||||||
|
};
|
||||||
|
fds_t fds[] MUI_PROGMEM =
|
||||||
|
MUI_FORM(1)
|
||||||
|
MUI_STYLE(0)
|
||||||
|
MUI_LABEL(5,12, "5x8 Font")
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MUI_U8G2_H
|
||||||
|
#define MUI_U8G2_H
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
#include "mui.h"
|
||||||
|
|
||||||
|
/*==========================================*/
|
||||||
|
/* C++ compatible */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define MUI_U8G2_COMMA ,
|
||||||
|
|
||||||
|
typedef const char * (*mui_u8g2_get_list_element_cb)(void *data, uint16_t index);
|
||||||
|
typedef uint16_t (*mui_u8g2_get_list_count_cb)(void *data);
|
||||||
|
|
||||||
|
struct mui_u8g2_list_struct
|
||||||
|
{
|
||||||
|
uint16_t *selection;
|
||||||
|
void *data;
|
||||||
|
mui_u8g2_get_list_element_cb get_list_element;
|
||||||
|
mui_u8g2_get_list_count_cb get_list_count;
|
||||||
|
} MUI_PROGMEM;
|
||||||
|
|
||||||
|
typedef const struct mui_u8g2_list_struct mui_u8g2_list_t;
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__AVR__)
|
||||||
|
# define mui_u8g2_list_get_selection_ptr(list) ((uint16_t *)mui_pgm_wread(&((list)->selection)))
|
||||||
|
# define mui_u8g2_list_get_data_ptr(list) ((void *)mui_pgm_wread(&((list)->data)))
|
||||||
|
# define mui_u8g2_list_get_element_cb(list) ((mui_u8g2_get_list_element_cb)mui_pgm_wread(&((list)->get_list_element)))
|
||||||
|
# define mui_u8g2_list_get_count_cb(list) ((mui_u8g2_get_list_count_cb)mui_pgm_wread(&((list)->get_list_count)))
|
||||||
|
#else
|
||||||
|
# define mui_u8g2_list_get_selection_ptr(list) ((list)->selection)
|
||||||
|
# define mui_u8g2_list_get_data_ptr(list) ((list)->data)
|
||||||
|
# define mui_u8g2_list_get_element_cb(list) ((list)->get_list_element)
|
||||||
|
# define mui_u8g2_list_get_count_cb(list) ((list)->get_list_count)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct mui_u8g2_u8_min_max_struct
|
||||||
|
{
|
||||||
|
uint8_t *value;
|
||||||
|
uint8_t min;
|
||||||
|
uint8_t max;
|
||||||
|
} MUI_PROGMEM;
|
||||||
|
|
||||||
|
typedef const struct mui_u8g2_u8_min_max_struct mui_u8g2_u8_min_max_t;
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__AVR__)
|
||||||
|
# define mui_u8g2_u8mm_get_min(u8mm) mui_pgm_read(&((u8mm)->min))
|
||||||
|
# define mui_u8g2_u8mm_get_max(u8mm) mui_pgm_read(&((u8mm)->max))
|
||||||
|
# define mui_u8g2_u8mm_get_valptr(u8mm) ((uint8_t *)mui_pgm_wread(&((u8mm)->value)))
|
||||||
|
#else
|
||||||
|
# define mui_u8g2_u8mm_get_min(u8mm) ((u8mm)->min)
|
||||||
|
# define mui_u8g2_u8mm_get_max(u8mm) ((u8mm)->max)
|
||||||
|
# define mui_u8g2_u8mm_get_valptr(u8mm) ((u8mm)->value)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct mui_u8g2_s8_min_max_struct
|
||||||
|
{
|
||||||
|
int8_t *value;
|
||||||
|
int8_t min;
|
||||||
|
int8_t max;
|
||||||
|
} MUI_PROGMEM;
|
||||||
|
|
||||||
|
typedef const struct mui_u8g2_s8_min_max_struct mui_u8g2_s8_min_max_t;
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__AVR__)
|
||||||
|
# define mui_u8g2_s8mm_get_min(u8mm) ((int8_t)mui_pgm_read(&((u8mm)->min)))
|
||||||
|
# define mui_u8g2_s8mm_get_max(u8mm) ((int8_t)mui_pgm_read(&((u8mm)->max)))
|
||||||
|
# define mui_u8g2_s8mm_get_valptr(u8mm) ((int8_t *)mui_pgm_wread(&((u8mm)->value)))
|
||||||
|
#else
|
||||||
|
# define mui_u8g2_s8mm_get_min(u8mm) ((u8mm)->min)
|
||||||
|
# define mui_u8g2_s8mm_get_max(u8mm) ((u8mm)->max)
|
||||||
|
# define mui_u8g2_s8mm_get_valptr(u8mm) ((u8mm)->value)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct mui_u8g2_u8_min_max_step_struct
|
||||||
|
{
|
||||||
|
uint8_t *value;
|
||||||
|
uint8_t min;
|
||||||
|
uint8_t max;
|
||||||
|
uint8_t step;
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t width; // added with issue 2200, might not be used by all bar graph functions
|
||||||
|
} MUI_PROGMEM;
|
||||||
|
|
||||||
|
typedef const struct mui_u8g2_u8_min_max_step_struct mui_u8g2_u8_min_max_step_t;
|
||||||
|
|
||||||
|
/* list of bit values for the "flags" variable */
|
||||||
|
#define MUI_MMS_2X_BAR 0x01
|
||||||
|
#define MUI_MMS_4X_BAR 0x02
|
||||||
|
#define MUI_MMS_SHOW_VALUE 0x04
|
||||||
|
#define MUI_MMS_NO_WRAP 0x08
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__AVR__)
|
||||||
|
# define mui_u8g2_u8mms_get_width(u8mm) mui_pgm_read(&((u8mm)->width))
|
||||||
|
# define mui_u8g2_u8mms_get_step(u8mm) mui_pgm_read(&((u8mm)->step))
|
||||||
|
# define mui_u8g2_u8mms_get_flags(u8mm) mui_pgm_read(&((u8mm)->flags))
|
||||||
|
# define mui_u8g2_u8mms_get_min(u8mm) mui_pgm_read(&((u8mm)->min))
|
||||||
|
# define mui_u8g2_u8mms_get_max(u8mm) mui_pgm_read(&((u8mm)->max))
|
||||||
|
# define mui_u8g2_u8mms_get_valptr(u8mm) ((uint8_t *)mui_pgm_wread(&((u8mm)->value)))
|
||||||
|
#else
|
||||||
|
# define mui_u8g2_u8mms_get_width(u8mm) ((u8mm)->width)
|
||||||
|
# define mui_u8g2_u8mms_get_step(u8mm) ((u8mm)->step)
|
||||||
|
# define mui_u8g2_u8mms_get_flags(u8mm) ((u8mm)->flags)
|
||||||
|
# define mui_u8g2_u8mms_get_min(u8mm) ((u8mm)->min)
|
||||||
|
# define mui_u8g2_u8mms_get_max(u8mm) ((u8mm)->max)
|
||||||
|
# define mui_u8g2_u8mms_get_valptr(u8mm) ((u8mm)->value)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* helper functions */
|
||||||
|
|
||||||
|
u8g2_uint_t mui_get_x(mui_t *ui);
|
||||||
|
u8g2_uint_t mui_get_y(mui_t *ui);
|
||||||
|
u8g2_t *mui_get_U8g2(mui_t *ui);
|
||||||
|
|
||||||
|
void mui_u8g2_draw_button_utf(mui_t *ui, u8g2_uint_t flags, u8g2_uint_t width, u8g2_uint_t padding_h, u8g2_uint_t padding_v, const char *text);
|
||||||
|
u8g2_uint_t mui_u8g2_get_pi_flags(mui_t *ui);
|
||||||
|
void mui_u8g2_draw_button_pi(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text);
|
||||||
|
u8g2_uint_t mui_u8g2_get_fi_flags(mui_t *ui);
|
||||||
|
void mui_u8g2_draw_button_fi(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text);
|
||||||
|
u8g2_uint_t mui_u8g2_get_pf_flags(mui_t *ui);
|
||||||
|
void mui_u8g2_draw_button_pf(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text);
|
||||||
|
u8g2_uint_t mui_u8g2_get_if_flags(mui_t *ui);
|
||||||
|
void mui_u8g2_draw_button_if(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ready to use field functions */
|
||||||
|
|
||||||
|
uint8_t mui_hline(mui_t *ui, uint8_t msg);
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_draw_text(mui_t *ui, uint8_t msg);
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_btn_goto_wm_fi(mui_t *ui, uint8_t msg); /* GIF */
|
||||||
|
uint8_t mui_u8g2_btn_goto_wm_if(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_btn_goto_w2_fi(mui_t *ui, uint8_t msg); /* GIF */
|
||||||
|
uint8_t mui_u8g2_btn_goto_w2_if(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_btn_goto_w1_pi(mui_t *ui, uint8_t msg); /* GIF */
|
||||||
|
uint8_t mui_u8g2_btn_goto_w1_fi(mui_t *ui, uint8_t msg); /* GIF */
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_btn_back_wm_fi(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_btn_back_wm_if(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_btn_back_w2_fi(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_btn_back_w2_if(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_btn_back_w1_pi(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_btn_back_w1_fi(mui_t *ui, uint8_t msg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_btn_exit_wm_fi(mui_t *ui, uint8_t msg); /* similar to 'mui_u8g2_btn_goto_wm_fi' but will exit the menu system */
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_u8_chkbox_wm_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE, MUI_XY */
|
||||||
|
uint8_t mui_u8g2_u8_radio_wm_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE,MUI_XYAT */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_u8_opt_line_wa_mse_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE,MUI_XYAT */
|
||||||
|
uint8_t mui_u8g2_u8_opt_line_wa_mse_pf(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE,MUI_XYAT */
|
||||||
|
uint8_t mui_u8g2_u8_opt_line_wa_mud_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE,MUI_XYAT */
|
||||||
|
uint8_t mui_u8g2_u8_opt_line_wa_mud_pf(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE,MUI_XYAT */
|
||||||
|
|
||||||
|
/* dropdown list / combo box */
|
||||||
|
/* The text part of the parent defines a '|' separated list of elements, which can be selected by the child. */
|
||||||
|
/* Argument is a form number where the child element is placed multiple times */
|
||||||
|
/* The child form does not require the ok button, because the child function will return to the parent with the select element */
|
||||||
|
uint8_t mui_u8g2_u8_opt_parent_wm_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE, MUI_XYAT */
|
||||||
|
uint8_t mui_u8g2_u8_opt_radio_child_wm_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE, MUI_XYA */
|
||||||
|
uint8_t mui_u8g2_u8_opt_radio_child_w1_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE, MUI_XYA */
|
||||||
|
uint8_t mui_u8g2_u8_opt_child_wm_pi(mui_t *ui, uint8_t msg); /* MUIF_VARIABLE, MUI_XYA */
|
||||||
|
/* Note: there is no opt_child_goto muif, because this can be done with mui_u8g2_goto_form_w1_pi */
|
||||||
|
|
||||||
|
/* (scrollable) jump menu */
|
||||||
|
/* The text part of the parent defines a '|' separated list of elements, which can be selected goto_form functions. */
|
||||||
|
/* Each '|' separated element must be prefixed with the form number (MUI_x) */
|
||||||
|
uint8_t mui_u8g2_goto_data(mui_t *ui, uint8_t msg); /* REF, MUIF_RO, MUI_DATA (WARNING: Must appear only once per form!!! */
|
||||||
|
uint8_t mui_u8g2_goto_form_w1_pi(mui_t *ui, uint8_t msg); /* REF, MUIF_BUTTON, MUI_XYA */
|
||||||
|
uint8_t mui_u8g2_goto_form_w1_pf(mui_t *ui, uint8_t msg); /* REF, MUIF_BUTTON, MUI_XYA */
|
||||||
|
|
||||||
|
|
||||||
|
/* character input */
|
||||||
|
uint8_t mui_u8g2_u8_char_wm_mud_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE,MUI_XY, usually requires a monospaced font line profont12 */
|
||||||
|
|
||||||
|
|
||||||
|
/*===== MUIF U8g2 Label =====*/
|
||||||
|
|
||||||
|
#define MUIF_U8G2_LABEL() MUIF_LABEL(mui_u8g2_draw_text)
|
||||||
|
|
||||||
|
|
||||||
|
/*===== data = u8g2 font data =====*/
|
||||||
|
|
||||||
|
//#define MUIF_U8G2_FONT_STYLE(n,font) MUIF("S" #n, 0, (void *)(font), mui_u8g2_set_font_style_function)
|
||||||
|
#define MUIF_U8G2_FONT_STYLE(n, font) { 'S', #n[0], 0, 0, (void *)(font), mui_u8g2_set_font_style_function}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_set_font_style_function(mui_t *ui, uint8_t msg);
|
||||||
|
|
||||||
|
|
||||||
|
/*===== data = mui_u8g2_u8_min_max_t* =====*/
|
||||||
|
|
||||||
|
/* gcc note: the macro uses array compound literals to extend the lifetime in C++, see last section in https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html */
|
||||||
|
#define MUIF_U8G2_U8_MIN_MAX(id, valptr, min, max, muif) \
|
||||||
|
MUIF(id, MUIF_CFLAG_IS_CURSOR_SELECTABLE, \
|
||||||
|
(void *)((mui_u8g2_u8_min_max_t [] ) {{ (valptr) MUI_U8G2_COMMA (min) MUI_U8G2_COMMA (max)}}), \
|
||||||
|
(muif))
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_u8_min_max_wm_mse_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_U8G2_U8_MIN_MAX, MUI_XY */
|
||||||
|
uint8_t mui_u8g2_u8_min_max_wm_mud_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_U8G2_U8_MIN_MAX, MUI_XY */
|
||||||
|
uint8_t mui_u8g2_u8_min_max_wm_mse_pf(mui_t *ui, uint8_t msg); /* GIF, MUIF_U8G2_U8_MIN_MAX, MUI_XY */
|
||||||
|
uint8_t mui_u8g2_u8_min_max_wm_mud_pf(mui_t *ui, uint8_t msg); /* GIF, MUIF_U8G2_U8_MIN_MAX, MUI_XY */
|
||||||
|
|
||||||
|
#define MUIF_U8G2_S8_MIN_MAX(id, valptr, min, max, muif) \
|
||||||
|
MUIF(id, MUIF_CFLAG_IS_CURSOR_SELECTABLE, \
|
||||||
|
(void *)((mui_u8g2_s8_min_max_t [] ) {{ (valptr) MUI_U8G2_COMMA (min) MUI_U8G2_COMMA (max)}}), \
|
||||||
|
(muif))
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_s8_min_max_wm_mse_pi(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_s8_min_max_wm_mud_pi(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_s8_min_max_wm_mse_pf(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_s8_min_max_wm_mud_pf(mui_t *ui, uint8_t msg);
|
||||||
|
|
||||||
|
|
||||||
|
/*===== data = mui_u8g2_u8_min_max_step_t* =====*/
|
||||||
|
|
||||||
|
/* gcc note: the macro uses array compound literals to extend the lifetime in C++, see last section in https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html */
|
||||||
|
#define MUIF_U8G2_U8_MIN_MAX_STEP(id, valptr, min, max, step, flags, muif) \
|
||||||
|
MUIF(id, MUIF_CFLAG_IS_CURSOR_SELECTABLE, \
|
||||||
|
(void *)((mui_u8g2_u8_min_max_step_t [] ) {{ (valptr) MUI_U8G2_COMMA (min) MUI_U8G2_COMMA (max) MUI_U8G2_COMMA (step) MUI_U8G2_COMMA (flags) MUI_U8G2_COMMA (0) }}), \
|
||||||
|
(muif))
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_u8_bar_wm_mse_pi(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_u8_bar_wm_mud_pi(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_u8_bar_wm_mse_pf(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_u8_bar_wm_mud_pf(mui_t *ui, uint8_t msg);
|
||||||
|
|
||||||
|
|
||||||
|
#define MUIF_U8G2_U8_MIN_MAX_STEP_WIDTH(id, valptr, min, max, step, width, flags, muif) \
|
||||||
|
MUIF(id, MUIF_CFLAG_IS_CURSOR_SELECTABLE, \
|
||||||
|
(void *)((mui_u8g2_u8_min_max_step_t [] ) {{ (valptr) MUI_U8G2_COMMA (min) MUI_U8G2_COMMA (max) MUI_U8G2_COMMA (step) MUI_U8G2_COMMA (flags) MUI_U8G2_COMMA (width) }}), \
|
||||||
|
(muif))
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_u8_fixed_width_bar_wm_mse_pi(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_u8_fixed_width_bar_wm_mud_pi(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_u8_fixed_width_bar_wm_mse_pf(mui_t *ui, uint8_t msg);
|
||||||
|
uint8_t mui_u8g2_u8_fixed_width_bar_wm_mud_pf(mui_t *ui, uint8_t msg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*===== data = mui_u8g2_list_t* =====*/
|
||||||
|
/* similar to mui_u8g2_u8_opt_line, but u16 and dynamic list */
|
||||||
|
|
||||||
|
|
||||||
|
#define MUIF_U8G2_U16_LIST(id, valptr, dataptr, getcb, cntcb, muif) \
|
||||||
|
MUIF(id, MUIF_CFLAG_IS_CURSOR_SELECTABLE, \
|
||||||
|
(void *)((mui_u8g2_list_t [] ) {{ (valptr) MUI_U8G2_COMMA (dataptr) MUI_U8G2_COMMA (getcb) MUI_U8G2_COMMA (cntcb)}}), \
|
||||||
|
(muif))
|
||||||
|
|
||||||
|
uint8_t mui_u8g2_u16_list_line_wa_mse_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_U8G2_U16_LIST, MUI_XYA, arg=pixel fieldsize */
|
||||||
|
uint8_t mui_u8g2_u16_list_line_wa_mud_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_U8G2_U16_LIST, MUI_XYA, arg=pixel fieldsize */
|
||||||
|
|
||||||
|
|
||||||
|
/* dropdown list / combo box with 16 size and callback functions for MUIF_U8G2_U16_LIST */
|
||||||
|
uint8_t mui_u8g2_u16_list_parent_wm_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_U8G2_U16_LIST, MUI_XYA, arg=subform */
|
||||||
|
uint8_t mui_u8g2_u16_list_child_w1_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_U8G2_U16_LIST, MUI_XYA, arg=sub element number */
|
||||||
|
uint8_t mui_u8g2_u16_list_goto_w1_pi(mui_t *ui, uint8_t msg); /* REF, MUIF_U8G2_U16_LIST first char of the string denotes the target form */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* MUI_U8G2_H */
|
||||||
|
|
||||||
4197
main/utilities/u8g2/src/u8g2.h
Normal file
4197
main/utilities/u8g2/src/u8g2.h
Normal file
File diff suppressed because it is too large
Load Diff
107
main/utilities/u8g2/src/u8g2_arc.c
Normal file
107
main/utilities/u8g2/src/u8g2_arc.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_arc.c
|
||||||
|
|
||||||
|
Contributed... see here: https://github.com/olikraus/u8g2/issues/2243
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2023, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void u8g2_draw_arc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t start, uint8_t end)
|
||||||
|
{
|
||||||
|
// Manage angle inputs
|
||||||
|
uint8_t full = (start == end);
|
||||||
|
uint8_t inverted = (start > end);
|
||||||
|
uint8_t a_start = inverted ? end : start;
|
||||||
|
uint8_t a_end = inverted ? start : end;
|
||||||
|
|
||||||
|
// Initialize variables
|
||||||
|
uint32_t ratio;
|
||||||
|
u8g2_int_t x = 0;
|
||||||
|
u8g2_int_t y = rad;
|
||||||
|
u8g2_int_t d = rad - 1;
|
||||||
|
|
||||||
|
// Trace arc radius with the Andres circle algorithm (process each pixel of a 1/8th circle of radius rad)
|
||||||
|
while (y >= x)
|
||||||
|
{
|
||||||
|
// Get the percentage of 1/8th circle drawn with a fast approximation of arctan(x/y)
|
||||||
|
ratio = x * 255 / y; // x/y [0..255]
|
||||||
|
ratio = ratio * (770195 - (ratio - 255) * (ratio + 941)) / 6137491; // arctan(x/y) [0..32]
|
||||||
|
|
||||||
|
// Fill the pixels of the 8 sections of the circle, but only on the arc defined by the angles (start and end)
|
||||||
|
if(full || ((ratio >= a_start && ratio < a_end) ^ inverted)) u8g2_DrawPixel(u8g2, x0 + y, y0 - x);
|
||||||
|
if(full || (((ratio + a_end) > 63 && (ratio + a_start) <= 63) ^ inverted)) u8g2_DrawPixel(u8g2, x0 + x, y0 - y);
|
||||||
|
if(full || (((ratio + 64) >= a_start && (ratio + 64) < a_end) ^ inverted)) u8g2_DrawPixel(u8g2, x0 - x, y0 - y);
|
||||||
|
if(full || (((ratio + a_end) > 127 && (ratio + a_start) <= 127) ^ inverted)) u8g2_DrawPixel(u8g2, x0 - y, y0 - x);
|
||||||
|
if(full || (((ratio + 128) >= a_start && (ratio + 128) < a_end) ^ inverted)) u8g2_DrawPixel(u8g2, x0 - y, y0 + x);
|
||||||
|
if(full || (((ratio + a_end) > 191 && (ratio + a_start) <= 191) ^ inverted)) u8g2_DrawPixel(u8g2, x0 - x, y0 + y);
|
||||||
|
if(full || (((ratio + 192) >= a_start && (ratio + 192) < a_end) ^ inverted)) u8g2_DrawPixel(u8g2, x0 + x, y0 + y);
|
||||||
|
if(full || (((ratio + a_end) > 255 && (ratio + a_start) <= 255) ^ inverted)) u8g2_DrawPixel(u8g2, x0 + y, y0 + x);
|
||||||
|
|
||||||
|
// Run Andres circle algorithm to get to the next pixel
|
||||||
|
if (d >= 2 * x)
|
||||||
|
{
|
||||||
|
d = d - 2 * x - 1;
|
||||||
|
x = x + 1;
|
||||||
|
}
|
||||||
|
else if (d < 2 * (rad - y))
|
||||||
|
{
|
||||||
|
d = d + 2 * y - 1;
|
||||||
|
y = y - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d = d + 2 * (y - x - 1);
|
||||||
|
y = y - 1;
|
||||||
|
x = x + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawArc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t start, uint8_t end)
|
||||||
|
{
|
||||||
|
/* check for bounding box */
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
{
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x0-rad, y0-rad, x0+rad+1, y0+rad+1) == 0 )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
|
||||||
|
/* draw arc */
|
||||||
|
u8g2_draw_arc(u8g2, x0, y0, rad, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
275
main/utilities/u8g2/src/u8g2_bitmap.c
Normal file
275
main/utilities/u8g2/src/u8g2_bitmap.c
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_bitmap.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_SetBitmapMode(u8g2_t *u8g2, uint8_t is_transparent) {
|
||||||
|
u8g2->bitmap_transparency = is_transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
x,y Position on the display
|
||||||
|
len Length of bitmap line in pixel. Note: This differs from u8glib which had a bytecount here.
|
||||||
|
b Pointer to the bitmap line.
|
||||||
|
Only draw pixels which are set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void u8g2_DrawHorizontalBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b)
|
||||||
|
{
|
||||||
|
uint8_t mask;
|
||||||
|
uint8_t color = u8g2->draw_color;
|
||||||
|
uint8_t ncolor = (color == 0 ? 1 : 0);
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
mask = 128;
|
||||||
|
while(len > 0)
|
||||||
|
{
|
||||||
|
if ( *b & mask ) {
|
||||||
|
u8g2->draw_color = color;
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
|
||||||
|
} else if ( u8g2->bitmap_transparency == 0 ) {
|
||||||
|
u8g2->draw_color = ncolor;
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
x++;
|
||||||
|
mask >>= 1;
|
||||||
|
if ( mask == 0 )
|
||||||
|
{
|
||||||
|
mask = 128;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
u8g2->draw_color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* u8glib compatible bitmap draw function */
|
||||||
|
void u8g2_DrawBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t cnt, u8g2_uint_t h, const uint8_t *bitmap)
|
||||||
|
{
|
||||||
|
u8g2_uint_t w;
|
||||||
|
w = cnt;
|
||||||
|
w *= 8;
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
while( h > 0 )
|
||||||
|
{
|
||||||
|
u8g2_DrawHorizontalBitmap(u8g2, x, y, w, bitmap);
|
||||||
|
bitmap += cnt;
|
||||||
|
y++;
|
||||||
|
h--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_DrawHXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b)
|
||||||
|
{
|
||||||
|
uint8_t mask;
|
||||||
|
uint8_t color = u8g2->draw_color;
|
||||||
|
uint8_t ncolor = (color == 0 ? 1 : 0);
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
mask = 1;
|
||||||
|
while(len > 0) {
|
||||||
|
uint8_t current_bit = (*b) & mask;
|
||||||
|
#ifdef OLD
|
||||||
|
if ( current_bit ) {
|
||||||
|
u8g2->draw_color = color;
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
|
||||||
|
} else if ( u8g2->bitmap_transparency == 0 ) {
|
||||||
|
u8g2->draw_color = ncolor;
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
mask <<= 1;
|
||||||
|
if ( mask == 0 )
|
||||||
|
{
|
||||||
|
mask = 1;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
len--;
|
||||||
|
#else
|
||||||
|
u8g2_uint_t run_length = 0;
|
||||||
|
// Determine the run length of consecutive bits with the same color
|
||||||
|
while (len > 0 && (current_bit == 0 ? (((*b) & mask) == 0) : (((*b) & mask) != 0 ) ))
|
||||||
|
{
|
||||||
|
run_length++;
|
||||||
|
x++;
|
||||||
|
mask <<= 1;
|
||||||
|
if (mask == 0)
|
||||||
|
{
|
||||||
|
mask = 1;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
if (current_bit)
|
||||||
|
{
|
||||||
|
u8g2->draw_color = color;
|
||||||
|
u8g2_DrawHVLine(u8g2, x - run_length, y, run_length, 0);
|
||||||
|
}
|
||||||
|
else if (u8g2->bitmap_transparency == 0)
|
||||||
|
{
|
||||||
|
u8g2->draw_color = ncolor;
|
||||||
|
u8g2_DrawHVLine(u8g2, x - run_length, y, run_length, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
u8g2->draw_color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_DrawXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap)
|
||||||
|
{
|
||||||
|
u8g2_uint_t blen;
|
||||||
|
blen = w;
|
||||||
|
blen += 7;
|
||||||
|
blen >>= 3;
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
while( h > 0 )
|
||||||
|
{
|
||||||
|
u8g2_DrawHXBM(u8g2, x, y, w, bitmap);
|
||||||
|
bitmap += blen;
|
||||||
|
y++;
|
||||||
|
h--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_DrawHXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b)
|
||||||
|
{
|
||||||
|
uint8_t mask;
|
||||||
|
uint8_t color = u8g2->draw_color;
|
||||||
|
uint8_t ncolor = (color == 0 ? 1 : 0);
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
mask = 1;
|
||||||
|
while(len > 0)
|
||||||
|
{
|
||||||
|
uint8_t current_bit = u8x8_pgm_read(b) & mask;
|
||||||
|
//#define OLD
|
||||||
|
#ifdef OLD
|
||||||
|
if ( current_bit ) {
|
||||||
|
u8g2->draw_color = color;
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
|
||||||
|
} else if( u8g2->bitmap_transparency == 0 ) {
|
||||||
|
u8g2->draw_color = ncolor;
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
x++;
|
||||||
|
mask <<= 1;
|
||||||
|
if ( mask == 0 )
|
||||||
|
{
|
||||||
|
mask = 1;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
len--;
|
||||||
|
#else
|
||||||
|
u8g2_uint_t run_length = 0;
|
||||||
|
// Determine the run length of consecutive bits with the same color
|
||||||
|
while (len > 0 && (current_bit == 0 ? ((u8x8_pgm_read(b) & mask) == 0) : ((u8x8_pgm_read(b) & mask) != 0 ) ))
|
||||||
|
{
|
||||||
|
run_length++;
|
||||||
|
x++;
|
||||||
|
mask <<= 1;
|
||||||
|
if (mask == 0)
|
||||||
|
{
|
||||||
|
mask = 1;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
if (current_bit)
|
||||||
|
{
|
||||||
|
u8g2->draw_color = color;
|
||||||
|
u8g2_DrawHVLine(u8g2, x - run_length, y, run_length, 0);
|
||||||
|
}
|
||||||
|
else if (u8g2->bitmap_transparency == 0)
|
||||||
|
{
|
||||||
|
u8g2->draw_color = ncolor;
|
||||||
|
u8g2_DrawHVLine(u8g2, x - run_length, y, run_length, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
u8g2->draw_color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_DrawXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap)
|
||||||
|
{
|
||||||
|
u8g2_uint_t blen;
|
||||||
|
blen = w;
|
||||||
|
blen += 7;
|
||||||
|
blen >>= 3;
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
while( h > 0 )
|
||||||
|
{
|
||||||
|
u8g2_DrawHXBMP(u8g2, x, y, w, bitmap);
|
||||||
|
bitmap += blen;
|
||||||
|
y++;
|
||||||
|
h--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
210
main/utilities/u8g2/src/u8g2_box.c
Normal file
210
main/utilities/u8g2/src/u8g2_box.c
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_box.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
draw a filled box
|
||||||
|
restriction: does not work for w = 0 or h = 0
|
||||||
|
*/
|
||||||
|
void u8g2_DrawBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
|
||||||
|
{
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
while( h != 0 )
|
||||||
|
{
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, w, 0);
|
||||||
|
y++;
|
||||||
|
h--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
draw a frame (empty box)
|
||||||
|
restriction: does not work for w = 0 or h = 0
|
||||||
|
*/
|
||||||
|
void u8g2_DrawFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
|
||||||
|
{
|
||||||
|
u8g2_uint_t xtmp = x;
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, w, 0);
|
||||||
|
if (h >= 2) {
|
||||||
|
h-=2;
|
||||||
|
y++;
|
||||||
|
if (h > 0) {
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, h, 1);
|
||||||
|
x+=w;
|
||||||
|
x--;
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, h, 1);
|
||||||
|
y+=h;
|
||||||
|
}
|
||||||
|
u8g2_DrawHVLine(u8g2, xtmp, y, w, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_DrawRBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)
|
||||||
|
{
|
||||||
|
u8g2_uint_t xl, yu;
|
||||||
|
u8g2_uint_t yl, xr;
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
xl = x;
|
||||||
|
xl += r;
|
||||||
|
yu = y;
|
||||||
|
yu += r;
|
||||||
|
|
||||||
|
xr = x;
|
||||||
|
xr += w;
|
||||||
|
xr -= r;
|
||||||
|
xr -= 1;
|
||||||
|
|
||||||
|
yl = y;
|
||||||
|
yl += h;
|
||||||
|
yl -= r;
|
||||||
|
yl -= 1;
|
||||||
|
|
||||||
|
u8g2_DrawDisc(u8g2, xl, yu, r, U8G2_DRAW_UPPER_LEFT);
|
||||||
|
u8g2_DrawDisc(u8g2, xr, yu, r, U8G2_DRAW_UPPER_RIGHT);
|
||||||
|
u8g2_DrawDisc(u8g2, xl, yl, r, U8G2_DRAW_LOWER_LEFT);
|
||||||
|
u8g2_DrawDisc(u8g2, xr, yl, r, U8G2_DRAW_LOWER_RIGHT);
|
||||||
|
|
||||||
|
{
|
||||||
|
u8g2_uint_t ww, hh;
|
||||||
|
|
||||||
|
ww = w;
|
||||||
|
ww -= r;
|
||||||
|
ww -= r;
|
||||||
|
xl++;
|
||||||
|
yu++;
|
||||||
|
|
||||||
|
if ( ww >= 3 )
|
||||||
|
{
|
||||||
|
ww -= 2;
|
||||||
|
u8g2_DrawBox(u8g2, xl, y, ww, r+1);
|
||||||
|
u8g2_DrawBox(u8g2, xl, yl, ww, r+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
hh = h;
|
||||||
|
hh -= r;
|
||||||
|
hh -= r;
|
||||||
|
//h--;
|
||||||
|
if ( hh >= 3 )
|
||||||
|
{
|
||||||
|
hh -= 2;
|
||||||
|
u8g2_DrawBox(u8g2, x, yu, w, hh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_DrawRFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)
|
||||||
|
{
|
||||||
|
u8g2_uint_t xl, yu;
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
xl = x;
|
||||||
|
xl += r;
|
||||||
|
yu = y;
|
||||||
|
yu += r;
|
||||||
|
|
||||||
|
{
|
||||||
|
u8g2_uint_t yl, xr;
|
||||||
|
|
||||||
|
xr = x;
|
||||||
|
xr += w;
|
||||||
|
xr -= r;
|
||||||
|
xr -= 1;
|
||||||
|
|
||||||
|
yl = y;
|
||||||
|
yl += h;
|
||||||
|
yl -= r;
|
||||||
|
yl -= 1;
|
||||||
|
|
||||||
|
u8g2_DrawCircle(u8g2, xl, yu, r, U8G2_DRAW_UPPER_LEFT);
|
||||||
|
u8g2_DrawCircle(u8g2, xr, yu, r, U8G2_DRAW_UPPER_RIGHT);
|
||||||
|
u8g2_DrawCircle(u8g2, xl, yl, r, U8G2_DRAW_LOWER_LEFT);
|
||||||
|
u8g2_DrawCircle(u8g2, xr, yl, r, U8G2_DRAW_LOWER_RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
u8g2_uint_t ww, hh;
|
||||||
|
|
||||||
|
ww = w;
|
||||||
|
ww -= r;
|
||||||
|
ww -= r;
|
||||||
|
hh = h;
|
||||||
|
hh -= r;
|
||||||
|
hh -= r;
|
||||||
|
|
||||||
|
xl++;
|
||||||
|
yu++;
|
||||||
|
|
||||||
|
if ( ww >= 3 )
|
||||||
|
{
|
||||||
|
ww -= 2;
|
||||||
|
h--;
|
||||||
|
u8g2_DrawHLine(u8g2, xl, y, ww);
|
||||||
|
u8g2_DrawHLine(u8g2, xl, y+h, ww);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( hh >= 3 )
|
||||||
|
{
|
||||||
|
hh -= 2;
|
||||||
|
w--;
|
||||||
|
u8g2_DrawVLine(u8g2, x, yu, hh);
|
||||||
|
u8g2_DrawVLine(u8g2, x+w, yu, hh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
213
main/utilities/u8g2/src/u8g2_buffer.c
Normal file
213
main/utilities/u8g2/src/u8g2_buffer.c
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_buffer.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
void u8g2_ClearBuffer(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
size_t cnt;
|
||||||
|
cnt = u8g2_GetU8x8(u8g2)->display_info->tile_width;
|
||||||
|
cnt *= u8g2->tile_buf_height;
|
||||||
|
cnt *= 8;
|
||||||
|
memset(u8g2->tile_buf_ptr, 0, cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
|
||||||
|
static void u8g2_send_tile_row(u8g2_t *u8g2, uint8_t src_tile_row, uint8_t dest_tile_row)
|
||||||
|
{
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint16_t offset;
|
||||||
|
uint8_t w;
|
||||||
|
|
||||||
|
w = u8g2_GetU8x8(u8g2)->display_info->tile_width;
|
||||||
|
offset = src_tile_row;
|
||||||
|
ptr = u8g2->tile_buf_ptr;
|
||||||
|
offset *= w;
|
||||||
|
offset *= 8;
|
||||||
|
ptr += offset;
|
||||||
|
u8x8_DrawTile(u8g2_GetU8x8(u8g2), 0, dest_tile_row, w, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
write the buffer to the display RAM.
|
||||||
|
For most displays, this will make the content visible to the user.
|
||||||
|
Some displays (like the SSD1606) require a u8x8_RefreshDisplay()
|
||||||
|
*/
|
||||||
|
static void u8g2_send_buffer(u8g2_t *u8g2) U8X8_NOINLINE;
|
||||||
|
static void u8g2_send_buffer(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
uint8_t src_row;
|
||||||
|
uint8_t src_max;
|
||||||
|
uint8_t dest_row;
|
||||||
|
uint8_t dest_max;
|
||||||
|
|
||||||
|
src_row = 0;
|
||||||
|
src_max = u8g2->tile_buf_height;
|
||||||
|
dest_row = u8g2->tile_curr_row;
|
||||||
|
dest_max = u8g2_GetU8x8(u8g2)->display_info->tile_height;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8g2_send_tile_row(u8g2, src_row, dest_row);
|
||||||
|
src_row++;
|
||||||
|
dest_row++;
|
||||||
|
} while( src_row < src_max && dest_row < dest_max );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* same as u8g2_send_buffer but also send the DISPLAY_REFRESH message (used by SSD1606) */
|
||||||
|
void u8g2_SendBuffer(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2_send_buffer(u8g2);
|
||||||
|
u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
void u8g2_SetBufferCurrTileRow(u8g2_t *u8g2, uint8_t row)
|
||||||
|
{
|
||||||
|
u8g2->tile_curr_row = row;
|
||||||
|
u8g2->cb->update_dimension(u8g2);
|
||||||
|
u8g2->cb->update_page_win(u8g2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_FirstPage(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
if ( u8g2->is_auto_page_clear )
|
||||||
|
{
|
||||||
|
u8g2_ClearBuffer(u8g2);
|
||||||
|
}
|
||||||
|
u8g2_SetBufferCurrTileRow(u8g2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8g2_NextPage(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
uint8_t row;
|
||||||
|
u8g2_send_buffer(u8g2);
|
||||||
|
row = u8g2->tile_curr_row;
|
||||||
|
row += u8g2->tile_buf_height;
|
||||||
|
if ( row >= u8g2_GetU8x8(u8g2)->display_info->tile_height )
|
||||||
|
{
|
||||||
|
u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( u8g2->is_auto_page_clear )
|
||||||
|
{
|
||||||
|
u8g2_ClearBuffer(u8g2);
|
||||||
|
}
|
||||||
|
u8g2_SetBufferCurrTileRow(u8g2, row);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
/*
|
||||||
|
Description:
|
||||||
|
Update a sub area of the display, given by tile position, width and height.
|
||||||
|
The arguments are "tile" coordinates. Any u8g2 rotation is ignored.
|
||||||
|
This procedure only checks whether full buffer mode is active.
|
||||||
|
There is no error checking for the arguments: It is the responsibility of the
|
||||||
|
user to ensure, that the provided arguments are correct.
|
||||||
|
|
||||||
|
Limitations:
|
||||||
|
- Only available in full buffer mode (will not do anything in page mode)
|
||||||
|
- Tile positions and sizes (pixel position divided by 8)
|
||||||
|
- Any display rotation/mirror is ignored
|
||||||
|
- Only works with displays, which support U8x8 API
|
||||||
|
- Will not send the e-paper refresh message (will probably not work with e-paper devices)
|
||||||
|
*/
|
||||||
|
void u8g2_UpdateDisplayArea(u8g2_t *u8g2, uint8_t tx, uint8_t ty, uint8_t tw, uint8_t th)
|
||||||
|
{
|
||||||
|
uint16_t page_size;
|
||||||
|
uint8_t *ptr;
|
||||||
|
|
||||||
|
/* check, whether we are in full buffer mode */
|
||||||
|
if ( u8g2->tile_buf_height != u8g2_GetU8x8(u8g2)->display_info->tile_height )
|
||||||
|
return; /* not in full buffer mode, do nothing */
|
||||||
|
|
||||||
|
page_size = u8g2->pixel_buf_width; /* 8*u8g2->u8g2_GetU8x8(u8g2)->display_info->tile_width */
|
||||||
|
|
||||||
|
ptr = u8g2_GetBufferPtr(u8g2);
|
||||||
|
ptr += tx*8;
|
||||||
|
ptr += page_size*ty;
|
||||||
|
|
||||||
|
while( th > 0 )
|
||||||
|
{
|
||||||
|
u8x8_DrawTile( u8g2_GetU8x8(u8g2), tx, ty, tw, ptr );
|
||||||
|
ptr += page_size;
|
||||||
|
ty++;
|
||||||
|
th--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* same as sendBuffer, but does not send the ePaper refresh message */
|
||||||
|
void u8g2_UpdateDisplay(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2_send_buffer(u8g2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
|
||||||
|
/* vertical_top memory architecture */
|
||||||
|
void u8g2_WriteBufferPBM(u8g2_t *u8g2, void (*out)(const char *s))
|
||||||
|
{
|
||||||
|
u8x8_capture_write_pbm_pre(u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), out);
|
||||||
|
u8x8_capture_write_pbm_buffer(u8g2_GetBufferPtr(u8g2), u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), u8x8_capture_get_pixel_1, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_WriteBufferXBM(u8g2_t *u8g2, void (*out)(const char *s))
|
||||||
|
{
|
||||||
|
u8x8_capture_write_xbm_pre(u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), out);
|
||||||
|
u8x8_capture_write_xbm_buffer(u8g2_GetBufferPtr(u8g2), u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), u8x8_capture_get_pixel_1, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* horizontal right memory architecture */
|
||||||
|
/* SH1122, LD7032, ST7920, ST7986, LC7981, T6963, SED1330, RA8835, MAX7219, LS0 */
|
||||||
|
void u8g2_WriteBufferPBM2(u8g2_t *u8g2, void (*out)(const char *s))
|
||||||
|
{
|
||||||
|
u8x8_capture_write_pbm_pre(u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), out);
|
||||||
|
u8x8_capture_write_pbm_buffer(u8g2_GetBufferPtr(u8g2), u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), u8x8_capture_get_pixel_2, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_WriteBufferXBM2(u8g2_t *u8g2, void (*out)(const char *s))
|
||||||
|
{
|
||||||
|
u8x8_capture_write_xbm_pre(u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), out);
|
||||||
|
u8x8_capture_write_xbm_buffer(u8g2_GetBufferPtr(u8g2), u8g2_GetBufferTileWidth(u8g2), u8g2_GetBufferTileHeight(u8g2), u8x8_capture_get_pixel_2, out);
|
||||||
|
}
|
||||||
|
|
||||||
313
main/utilities/u8g2/src/u8g2_button.c
Normal file
313
main/utilities/u8g2/src/u8g2_button.c
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_button.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Description:
|
||||||
|
Draws normal or inverted text with optional frame around text.
|
||||||
|
The text (and the frame) can be horizontally centered around the provided reference position.
|
||||||
|
This procedure will use the current draw color and current font. The height of the frame
|
||||||
|
depends on the setting of setFontRefHeightText(), setFontRefHeightExtendedText() or setFontRefHeightAll()
|
||||||
|
|
||||||
|
|
||||||
|
Note 1: drawColor 2 (XOR) is not supported. Result will be broken with draw color 2.
|
||||||
|
Note 2: This procedure will enforce font mode 1 (transparent mode)
|
||||||
|
Note 3: Some fonts may add an extra gap on the right side. This is a font problem and can not be avoided (for example inb16 has this problem).
|
||||||
|
|
||||||
|
|
||||||
|
The height of the button is defined by the current font and
|
||||||
|
setFontRefHeightText,
|
||||||
|
setFontRefHeightExtendedText
|
||||||
|
setFontRefHeightAll
|
||||||
|
Right padding might be influenced by the font.
|
||||||
|
For example u8g2_font_inb16 may add an extra pixel gap (increase padding by one)
|
||||||
|
on the right side.
|
||||||
|
The current draw color is considered, but only draw color 0 and 1 are supported
|
||||||
|
|
||||||
|
This function requires transparent font mode: setFontMode(1)
|
||||||
|
|
||||||
|
Side effect: Font transparent mode is enabled setFontMode(1)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
flags:
|
||||||
|
|
||||||
|
U8G2_BTN_BW1 0x01
|
||||||
|
U8G2_BTN_BW2 0x02
|
||||||
|
U8G2_BTN_BW3 0x03
|
||||||
|
|
||||||
|
|
||||||
|
U8G2_BTN_SHADOW0 0x08
|
||||||
|
U8G2_BTN_SHADOW1 0x10
|
||||||
|
U8G2_BTN_SHADOW2 0x18
|
||||||
|
|
||||||
|
U8G2_BTN_INV 0x20
|
||||||
|
|
||||||
|
U8G2_BTN_HCENTER 0x40
|
||||||
|
|
||||||
|
U8G2_BTN_XFRAME 0x80
|
||||||
|
|
||||||
|
Total size without shadow: width+2*padding_h+2*border
|
||||||
|
Total size with U8G2_BTN_SHADOW0: width+2*padding_h+3*border
|
||||||
|
Total size with U8G2_BTN_SHADOW1: width+2*padding_h+3*border+1
|
||||||
|
Total size with U8G2_BTN_SHADOW2: width+2*padding_h+3*border+2
|
||||||
|
|
||||||
|
U8G2_BTN_XFRAME:
|
||||||
|
draw another one pixel frame with one pixel gap, will not look good with shadow
|
||||||
|
*/
|
||||||
|
|
||||||
|
void u8g2_DrawButtonFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t text_width, u8g2_uint_t padding_h, u8g2_uint_t padding_v)
|
||||||
|
{
|
||||||
|
u8g2_uint_t w = text_width;
|
||||||
|
|
||||||
|
u8g2_uint_t xx, yy, ww, hh;
|
||||||
|
|
||||||
|
u8g2_uint_t gap_frame = U8G2_BTN_BW_MASK+1;
|
||||||
|
|
||||||
|
u8g2_uint_t border_width = flags & U8G2_BTN_BW_MASK;
|
||||||
|
|
||||||
|
int8_t a = u8g2_GetAscent(u8g2);
|
||||||
|
int8_t d = u8g2_GetDescent(u8g2);
|
||||||
|
|
||||||
|
uint8_t color_backup = u8g2->draw_color;
|
||||||
|
|
||||||
|
|
||||||
|
if ( flags & U8G2_BTN_XFRAME )
|
||||||
|
{
|
||||||
|
border_width++;
|
||||||
|
gap_frame = border_width;
|
||||||
|
border_width++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
|
||||||
|
xx = x;
|
||||||
|
xx -= padding_h;
|
||||||
|
xx -= border_width;
|
||||||
|
ww = w+2*padding_h+2*border_width;
|
||||||
|
|
||||||
|
yy = y;
|
||||||
|
yy += u8g2->font_calc_vref(u8g2);
|
||||||
|
yy -= a;
|
||||||
|
yy -= padding_v;
|
||||||
|
yy -= border_width;
|
||||||
|
hh = a-d+2*padding_v+2*border_width;
|
||||||
|
if ( border_width == 0 )
|
||||||
|
break;
|
||||||
|
if ( border_width == gap_frame )
|
||||||
|
{
|
||||||
|
u8g2_SetDrawColor(u8g2, color_backup == 0 ? 1 : 0);
|
||||||
|
}
|
||||||
|
u8g2_DrawFrame(u8g2, xx, yy, ww, hh);
|
||||||
|
u8g2_SetDrawColor(u8g2, color_backup);
|
||||||
|
|
||||||
|
if ( flags & U8G2_BTN_SHADOW_MASK )
|
||||||
|
{
|
||||||
|
if ( border_width == (flags & U8G2_BTN_BW_MASK) )
|
||||||
|
{
|
||||||
|
u8g2_uint_t i;
|
||||||
|
u8g2_uint_t shadow_gap = (flags & U8G2_BTN_SHADOW_MASK) >> U8G2_BTN_SHADOW_POS;
|
||||||
|
shadow_gap--;
|
||||||
|
for( i = 0; i < border_width; i++ )
|
||||||
|
{
|
||||||
|
u8g2_DrawHLine(u8g2, xx+border_width+shadow_gap,yy+hh+i+shadow_gap,ww);
|
||||||
|
u8g2_DrawVLine(u8g2, xx+ww+i+shadow_gap,yy+border_width+shadow_gap,hh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
border_width--;
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
if ( flags & U8G2_BTN_INV )
|
||||||
|
{
|
||||||
|
u8g2_SetDrawColor(u8g2, 2); /* XOR */
|
||||||
|
u8g2_DrawBox(u8g2, xx, yy, ww, hh);
|
||||||
|
u8g2_SetDrawColor(u8g2, color_backup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawButtonUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t width, u8g2_uint_t padding_h, u8g2_uint_t padding_v, const char *text)
|
||||||
|
{
|
||||||
|
u8g2_uint_t w = u8g2_GetUTF8Width(u8g2, text);
|
||||||
|
|
||||||
|
u8g2_uint_t text_x_offset = 0;
|
||||||
|
|
||||||
|
if ( flags & U8G2_BTN_HCENTER )
|
||||||
|
x -= (w+1)/2;
|
||||||
|
|
||||||
|
if ( w < width )
|
||||||
|
{
|
||||||
|
if ( flags & U8G2_BTN_HCENTER )
|
||||||
|
{
|
||||||
|
text_x_offset = (width-w)/2;
|
||||||
|
}
|
||||||
|
w = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8g2_SetFontMode(u8g2, 1);
|
||||||
|
u8g2_DrawUTF8(u8g2, x,y, text);
|
||||||
|
u8g2_DrawButtonFrame(u8g2, x-text_x_offset, y, flags, w, padding_h, padding_v);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NOT_USED
|
||||||
|
void u8g2_Draw4Pixel(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w)
|
||||||
|
{
|
||||||
|
u8g2_DrawPixel(u8g2, x,y-1);
|
||||||
|
u8g2_DrawPixel(u8g2, x+w-1,y-1);
|
||||||
|
u8g2_DrawPixel(u8g2, x+w-1,y-w);
|
||||||
|
u8g2_DrawPixel(u8g2, x,y-w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawRadio(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t is_checked)
|
||||||
|
{
|
||||||
|
uint8_t color_backup = u8g2->draw_color;
|
||||||
|
u8g2_DrawCheckbox(u8g2, x,y,w,is_checked);
|
||||||
|
u8g2_SetDrawColor(u8g2, 2);
|
||||||
|
u8g2_Draw4Pixel(u8g2, x,y,w);
|
||||||
|
if ( is_checked )
|
||||||
|
{
|
||||||
|
//u8g2_Draw4Pixel(u8g2, x+2,y-2,w-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8g2_SetDrawColor(u8g2, color_backup );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _THIS_CODE_SHOULD_BE_REWRITTEN_WITHOUT_PADWIDTH_
|
||||||
|
|
||||||
|
/*
|
||||||
|
Shadow is not supported
|
||||||
|
Note: radius must be at least as high as the border width
|
||||||
|
|
||||||
|
border width | good radius values
|
||||||
|
1 | 3, 5, 7, 8, ...
|
||||||
|
2 | 3, 5, 7, 8, ...
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void u8g2_DrawRButtonUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t padding_h_or_width, u8g2_uint_t padding_v, u8g2_uint_t r, const char *text)
|
||||||
|
{
|
||||||
|
u8g2_uint_t w = u8g2_GetUTF8Width(u8g2, text);
|
||||||
|
//u8g2_uint_t w = u8g2_GetExactStrWidth(u8g2, text);
|
||||||
|
|
||||||
|
u8g2_uint_t xx, yy, ww, hh;
|
||||||
|
|
||||||
|
u8g2_uint_t border_width = flags & U8G2_BTN_BW_MASK;
|
||||||
|
u8g2_uint_t padding_h = padding_h_or_width;
|
||||||
|
u8g2_uint_t text_x_offset = 0; // used for U8G2_BTN_PADWIDTH mode
|
||||||
|
|
||||||
|
int8_t a = u8g2_GetAscent(u8g2);
|
||||||
|
int8_t d = u8g2_GetDescent(u8g2);
|
||||||
|
uint8_t color_backup = u8g2->draw_color;
|
||||||
|
|
||||||
|
|
||||||
|
if ( flags & U8G2_BTN_HCENTER )
|
||||||
|
x -= w/2;
|
||||||
|
|
||||||
|
if ( flags & U8G2_BTN_PADWIDTH )
|
||||||
|
{
|
||||||
|
padding_h = 0;
|
||||||
|
if ( w < padding_h_or_width )
|
||||||
|
{
|
||||||
|
if ( flags & U8G2_BTN_HCENTER )
|
||||||
|
{
|
||||||
|
text_x_offset = (padding_h_or_width-w)/2;
|
||||||
|
}
|
||||||
|
w = padding_h_or_width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u8g2_SetFontMode(u8g2, 1);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if ( padding_h >= u8g2_GetDisplayWidth(u8g2)/2 ) // padding_h is zero if U8G2_BTN_PADWIDTH is set
|
||||||
|
{
|
||||||
|
xx = (flags & U8G2_BTN_BW_MASK) - border_width;
|
||||||
|
ww = u8g2_GetDisplayWidth(u8g2);
|
||||||
|
ww -= 2*((flags & U8G2_BTN_BW_MASK) - border_width);
|
||||||
|
//printf("xx=%d ww=%d\n", xx, ww);
|
||||||
|
//printf("clip_x1=%d clip_x0=%d\n", u8g2->clip_x1, u8g2->clip_x0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xx = x;
|
||||||
|
xx -= text_x_offset;
|
||||||
|
xx -= padding_h;
|
||||||
|
xx -= border_width;
|
||||||
|
ww = w+2*padding_h+2*border_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
yy = y;
|
||||||
|
yy += u8g2->font_calc_vref(u8g2);
|
||||||
|
yy -= a;
|
||||||
|
yy -= padding_v;
|
||||||
|
yy -= border_width;
|
||||||
|
hh = a-d+2*padding_v+2*border_width;
|
||||||
|
if ( border_width == 0 )
|
||||||
|
break;
|
||||||
|
u8g2_DrawRFrame(u8g2, xx, yy, ww, hh, r);
|
||||||
|
if ( (flags & U8G2_BTN_BW_MASK) > 1 )
|
||||||
|
u8g2_DrawRFrame(u8g2, xx, yy, ww, hh, r+1);
|
||||||
|
|
||||||
|
border_width--;
|
||||||
|
if ( r > 1 )
|
||||||
|
r--;
|
||||||
|
}
|
||||||
|
if ( flags & U8G2_BTN_INV )
|
||||||
|
{
|
||||||
|
u8g2_DrawRBox(u8g2, xx, yy, ww, hh,r);
|
||||||
|
u8g2_SetDrawColor(u8g2, 1-u8g2->draw_color);
|
||||||
|
}
|
||||||
|
u8g2_DrawUTF8(u8g2, x,y, text);
|
||||||
|
u8g2_SetDrawColor(u8g2, color_backup);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
479
main/utilities/u8g2/src/u8g2_circle.c
Normal file
479
main/utilities/u8g2/src/u8g2_circle.c
Normal file
@ -0,0 +1,479 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_circle.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
/*==============================================*/
|
||||||
|
/* Circle */
|
||||||
|
|
||||||
|
static void u8g2_draw_circle_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
|
||||||
|
|
||||||
|
static void u8g2_draw_circle_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
|
||||||
|
{
|
||||||
|
/* upper right */
|
||||||
|
if ( option & U8G2_DRAW_UPPER_RIGHT )
|
||||||
|
{
|
||||||
|
u8g2_DrawPixel(u8g2, x0 + x, y0 - y);
|
||||||
|
u8g2_DrawPixel(u8g2, x0 + y, y0 - x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* upper left */
|
||||||
|
if ( option & U8G2_DRAW_UPPER_LEFT )
|
||||||
|
{
|
||||||
|
u8g2_DrawPixel(u8g2, x0 - x, y0 - y);
|
||||||
|
u8g2_DrawPixel(u8g2, x0 - y, y0 - x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lower right */
|
||||||
|
if ( option & U8G2_DRAW_LOWER_RIGHT )
|
||||||
|
{
|
||||||
|
u8g2_DrawPixel(u8g2, x0 + x, y0 + y);
|
||||||
|
u8g2_DrawPixel(u8g2, x0 + y, y0 + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lower left */
|
||||||
|
if ( option & U8G2_DRAW_LOWER_LEFT )
|
||||||
|
{
|
||||||
|
u8g2_DrawPixel(u8g2, x0 - x, y0 + y);
|
||||||
|
u8g2_DrawPixel(u8g2, x0 - y, y0 + x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void u8g2_draw_circle(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
|
||||||
|
{
|
||||||
|
u8g2_int_t f;
|
||||||
|
u8g2_int_t ddF_x;
|
||||||
|
u8g2_int_t ddF_y;
|
||||||
|
u8g2_uint_t x;
|
||||||
|
u8g2_uint_t y;
|
||||||
|
|
||||||
|
f = 1;
|
||||||
|
f -= rad;
|
||||||
|
ddF_x = 1;
|
||||||
|
ddF_y = 0;
|
||||||
|
ddF_y -= rad;
|
||||||
|
ddF_y *= 2;
|
||||||
|
x = 0;
|
||||||
|
y = rad;
|
||||||
|
|
||||||
|
u8g2_draw_circle_section(u8g2, x, y, x0, y0, option);
|
||||||
|
|
||||||
|
while ( x < y )
|
||||||
|
{
|
||||||
|
if (f >= 0)
|
||||||
|
{
|
||||||
|
y--;
|
||||||
|
ddF_y += 2;
|
||||||
|
f += ddF_y;
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
ddF_x += 2;
|
||||||
|
f += ddF_x;
|
||||||
|
|
||||||
|
u8g2_draw_circle_section(u8g2, x, y, x0, y0, option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawCircle(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
|
||||||
|
{
|
||||||
|
/* check for bounding box */
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
{
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x0-rad, y0-rad, x0+rad+1, y0+rad+1) == 0 )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
|
||||||
|
/* draw circle */
|
||||||
|
u8g2_draw_circle(u8g2, x0, y0, rad, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==============================================*/
|
||||||
|
/* Disk */
|
||||||
|
|
||||||
|
static void u8g2_draw_disc_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
|
||||||
|
|
||||||
|
static void u8g2_draw_disc_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
|
||||||
|
{
|
||||||
|
/* upper right */
|
||||||
|
if ( option & U8G2_DRAW_UPPER_RIGHT )
|
||||||
|
{
|
||||||
|
u8g2_DrawVLine(u8g2, x0+x, y0-y, y+1);
|
||||||
|
u8g2_DrawVLine(u8g2, x0+y, y0-x, x+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* upper left */
|
||||||
|
if ( option & U8G2_DRAW_UPPER_LEFT )
|
||||||
|
{
|
||||||
|
u8g2_DrawVLine(u8g2, x0-x, y0-y, y+1);
|
||||||
|
u8g2_DrawVLine(u8g2, x0-y, y0-x, x+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lower right */
|
||||||
|
if ( option & U8G2_DRAW_LOWER_RIGHT )
|
||||||
|
{
|
||||||
|
u8g2_DrawVLine(u8g2, x0+x, y0, y+1);
|
||||||
|
u8g2_DrawVLine(u8g2, x0+y, y0, x+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lower left */
|
||||||
|
if ( option & U8G2_DRAW_LOWER_LEFT )
|
||||||
|
{
|
||||||
|
u8g2_DrawVLine(u8g2, x0-x, y0, y+1);
|
||||||
|
u8g2_DrawVLine(u8g2, x0-y, y0, x+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void u8g2_draw_disc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
|
||||||
|
{
|
||||||
|
u8g2_int_t f;
|
||||||
|
u8g2_int_t ddF_x;
|
||||||
|
u8g2_int_t ddF_y;
|
||||||
|
u8g2_uint_t x;
|
||||||
|
u8g2_uint_t y;
|
||||||
|
|
||||||
|
f = 1;
|
||||||
|
f -= rad;
|
||||||
|
ddF_x = 1;
|
||||||
|
ddF_y = 0;
|
||||||
|
ddF_y -= rad;
|
||||||
|
ddF_y *= 2;
|
||||||
|
x = 0;
|
||||||
|
y = rad;
|
||||||
|
|
||||||
|
u8g2_draw_disc_section(u8g2, x, y, x0, y0, option);
|
||||||
|
|
||||||
|
while ( x < y )
|
||||||
|
{
|
||||||
|
if (f >= 0)
|
||||||
|
{
|
||||||
|
y--;
|
||||||
|
ddF_y += 2;
|
||||||
|
f += ddF_y;
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
ddF_x += 2;
|
||||||
|
f += ddF_x;
|
||||||
|
|
||||||
|
u8g2_draw_disc_section(u8g2, x, y, x0, y0, option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawDisc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
|
||||||
|
{
|
||||||
|
/* check for bounding box */
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
{
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x0-rad, y0-rad, x0+rad+1, y0+rad+1) == 0 )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
/* draw disc */
|
||||||
|
u8g2_draw_disc(u8g2, x0, y0, rad, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==============================================*/
|
||||||
|
/* Ellipse */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Source:
|
||||||
|
Foley, Computer Graphics, p 90
|
||||||
|
*/
|
||||||
|
static void u8g2_draw_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
|
||||||
|
static void u8g2_draw_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
|
||||||
|
{
|
||||||
|
/* upper right */
|
||||||
|
if ( option & U8G2_DRAW_UPPER_RIGHT )
|
||||||
|
{
|
||||||
|
u8g2_DrawPixel(u8g2, x0 + x, y0 - y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* upper left */
|
||||||
|
if ( option & U8G2_DRAW_UPPER_LEFT )
|
||||||
|
{
|
||||||
|
u8g2_DrawPixel(u8g2, x0 - x, y0 - y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lower right */
|
||||||
|
if ( option & U8G2_DRAW_LOWER_RIGHT )
|
||||||
|
{
|
||||||
|
u8g2_DrawPixel(u8g2, x0 + x, y0 + y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lower left */
|
||||||
|
if ( option & U8G2_DRAW_LOWER_LEFT )
|
||||||
|
{
|
||||||
|
u8g2_DrawPixel(u8g2, x0 - x, y0 + y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void u8g2_draw_ellipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
|
||||||
|
{
|
||||||
|
u8g2_uint_t x, y;
|
||||||
|
u8g2_long_t xchg, ychg;
|
||||||
|
u8g2_long_t err;
|
||||||
|
u8g2_long_t rxrx2;
|
||||||
|
u8g2_long_t ryry2;
|
||||||
|
u8g2_long_t stopx, stopy;
|
||||||
|
|
||||||
|
rxrx2 = rx;
|
||||||
|
rxrx2 *= rx;
|
||||||
|
rxrx2 *= 2;
|
||||||
|
|
||||||
|
ryry2 = ry;
|
||||||
|
ryry2 *= ry;
|
||||||
|
ryry2 *= 2;
|
||||||
|
|
||||||
|
x = rx;
|
||||||
|
y = 0;
|
||||||
|
|
||||||
|
xchg = 1;
|
||||||
|
xchg -= rx;
|
||||||
|
xchg -= rx;
|
||||||
|
xchg *= ry;
|
||||||
|
xchg *= ry;
|
||||||
|
|
||||||
|
ychg = rx;
|
||||||
|
ychg *= rx;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
stopx = ryry2;
|
||||||
|
stopx *= rx;
|
||||||
|
stopy = 0;
|
||||||
|
|
||||||
|
while( stopx >= stopy )
|
||||||
|
{
|
||||||
|
u8g2_draw_ellipse_section(u8g2, x, y, x0, y0, option);
|
||||||
|
y++;
|
||||||
|
stopy += rxrx2;
|
||||||
|
err += ychg;
|
||||||
|
ychg += rxrx2;
|
||||||
|
if ( 2*err+xchg > 0 )
|
||||||
|
{
|
||||||
|
x--;
|
||||||
|
stopx -= ryry2;
|
||||||
|
err += xchg;
|
||||||
|
xchg += ryry2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
y = ry;
|
||||||
|
|
||||||
|
xchg = ry;
|
||||||
|
xchg *= ry;
|
||||||
|
|
||||||
|
ychg = 1;
|
||||||
|
ychg -= ry;
|
||||||
|
ychg -= ry;
|
||||||
|
ychg *= rx;
|
||||||
|
ychg *= rx;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
stopx = 0;
|
||||||
|
|
||||||
|
stopy = rxrx2;
|
||||||
|
stopy *= ry;
|
||||||
|
|
||||||
|
|
||||||
|
while( stopx <= stopy )
|
||||||
|
{
|
||||||
|
u8g2_draw_ellipse_section(u8g2, x, y, x0, y0, option);
|
||||||
|
x++;
|
||||||
|
stopx += ryry2;
|
||||||
|
err += xchg;
|
||||||
|
xchg += ryry2;
|
||||||
|
if ( 2*err+ychg > 0 )
|
||||||
|
{
|
||||||
|
y--;
|
||||||
|
stopy -= rxrx2;
|
||||||
|
err += ychg;
|
||||||
|
ychg += rxrx2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawEllipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
|
||||||
|
{
|
||||||
|
/* check for bounding box */
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
{
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x0-rx, y0-ry, x0+rx+1, y0+ry+1) == 0 )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
u8g2_draw_ellipse(u8g2, x0, y0, rx, ry, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==============================================*/
|
||||||
|
/* Filled Ellipse */
|
||||||
|
|
||||||
|
static void u8g2_draw_filled_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
|
||||||
|
static void u8g2_draw_filled_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
|
||||||
|
{
|
||||||
|
/* upper right */
|
||||||
|
if ( option & U8G2_DRAW_UPPER_RIGHT )
|
||||||
|
{
|
||||||
|
u8g2_DrawVLine(u8g2, x0+x, y0-y, y+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* upper left */
|
||||||
|
if ( option & U8G2_DRAW_UPPER_LEFT )
|
||||||
|
{
|
||||||
|
u8g2_DrawVLine(u8g2, x0-x, y0-y, y+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lower right */
|
||||||
|
if ( option & U8G2_DRAW_LOWER_RIGHT )
|
||||||
|
{
|
||||||
|
u8g2_DrawVLine(u8g2, x0+x, y0, y+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lower left */
|
||||||
|
if ( option & U8G2_DRAW_LOWER_LEFT )
|
||||||
|
{
|
||||||
|
u8g2_DrawVLine(u8g2, x0-x, y0, y+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void u8g2_draw_filled_ellipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
|
||||||
|
{
|
||||||
|
u8g2_uint_t x, y;
|
||||||
|
u8g2_long_t xchg, ychg;
|
||||||
|
u8g2_long_t err;
|
||||||
|
u8g2_long_t rxrx2;
|
||||||
|
u8g2_long_t ryry2;
|
||||||
|
u8g2_long_t stopx, stopy;
|
||||||
|
|
||||||
|
rxrx2 = rx;
|
||||||
|
rxrx2 *= rx;
|
||||||
|
rxrx2 *= 2;
|
||||||
|
|
||||||
|
ryry2 = ry;
|
||||||
|
ryry2 *= ry;
|
||||||
|
ryry2 *= 2;
|
||||||
|
|
||||||
|
x = rx;
|
||||||
|
y = 0;
|
||||||
|
|
||||||
|
xchg = 1;
|
||||||
|
xchg -= rx;
|
||||||
|
xchg -= rx;
|
||||||
|
xchg *= ry;
|
||||||
|
xchg *= ry;
|
||||||
|
|
||||||
|
ychg = rx;
|
||||||
|
ychg *= rx;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
stopx = ryry2;
|
||||||
|
stopx *= rx;
|
||||||
|
stopy = 0;
|
||||||
|
|
||||||
|
while( stopx >= stopy )
|
||||||
|
{
|
||||||
|
u8g2_draw_filled_ellipse_section(u8g2, x, y, x0, y0, option);
|
||||||
|
y++;
|
||||||
|
stopy += rxrx2;
|
||||||
|
err += ychg;
|
||||||
|
ychg += rxrx2;
|
||||||
|
if ( 2*err+xchg > 0 )
|
||||||
|
{
|
||||||
|
x--;
|
||||||
|
stopx -= ryry2;
|
||||||
|
err += xchg;
|
||||||
|
xchg += ryry2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
y = ry;
|
||||||
|
|
||||||
|
xchg = ry;
|
||||||
|
xchg *= ry;
|
||||||
|
|
||||||
|
ychg = 1;
|
||||||
|
ychg -= ry;
|
||||||
|
ychg -= ry;
|
||||||
|
ychg *= rx;
|
||||||
|
ychg *= rx;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
stopx = 0;
|
||||||
|
|
||||||
|
stopy = rxrx2;
|
||||||
|
stopy *= ry;
|
||||||
|
|
||||||
|
|
||||||
|
while( stopx <= stopy )
|
||||||
|
{
|
||||||
|
u8g2_draw_filled_ellipse_section(u8g2, x, y, x0, y0, option);
|
||||||
|
x++;
|
||||||
|
stopx += ryry2;
|
||||||
|
err += xchg;
|
||||||
|
xchg += ryry2;
|
||||||
|
if ( 2*err+ychg > 0 )
|
||||||
|
{
|
||||||
|
y--;
|
||||||
|
stopy -= rxrx2;
|
||||||
|
err += ychg;
|
||||||
|
ychg += rxrx2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawFilledEllipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
|
||||||
|
{
|
||||||
|
/* check for bounding box */
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
{
|
||||||
|
if ( u8g2_IsIntersection(u8g2, x0-rx, y0-ry, x0+rx+1, y0+ry+1) == 0 )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
|
u8g2_draw_filled_ellipse(u8g2, x0, y0, rx, ry, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
54
main/utilities/u8g2/src/u8g2_cleardisplay.c
Normal file
54
main/utilities/u8g2/src/u8g2_cleardisplay.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_cleardisplay.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
/* Clear screen buffer & display reliable for all u8g2 displays. */
|
||||||
|
/* This is done with u8g2 picture loop, because we can not use the u8x8 function in all cases */
|
||||||
|
void u8g2_ClearDisplay(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2_FirstPage(u8g2);
|
||||||
|
do {
|
||||||
|
} while ( u8g2_NextPage(u8g2) );
|
||||||
|
/*
|
||||||
|
This function is usually called during startup (u8g2.begin()).
|
||||||
|
However the user might want to use full buffer mode with clear and
|
||||||
|
send commands.
|
||||||
|
This will not work because the current tile row is modified by the picture
|
||||||
|
loop above. To fix this, reset the tile row to 0, issue #370
|
||||||
|
A workaround would be, that the user sets the current tile row to 0 manually.
|
||||||
|
*/
|
||||||
|
u8g2_SetBufferCurrTileRow(u8g2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
72
main/utilities/u8g2/src/u8g2_d_memory.c
Normal file
72
main/utilities/u8g2/src/u8g2_d_memory.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/* u8g2_d_memory.c */
|
||||||
|
/* generated code, codebuild, u8g2 project */
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
uint8_t *u8g2_m_16_4_1(uint8_t *page_cnt)
|
||||||
|
{
|
||||||
|
#ifdef U8G2_USE_DYNAMIC_ALLOC
|
||||||
|
*page_cnt = 1;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
static uint8_t buf[128];
|
||||||
|
*page_cnt = 1;
|
||||||
|
return buf;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
uint8_t *u8g2_m_16_4_2(uint8_t *page_cnt)
|
||||||
|
{
|
||||||
|
#ifdef U8G2_USE_DYNAMIC_ALLOC
|
||||||
|
*page_cnt = 2;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
static uint8_t buf[256];
|
||||||
|
*page_cnt = 2;
|
||||||
|
return buf;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
uint8_t *u8g2_m_16_4_f(uint8_t *page_cnt)
|
||||||
|
{
|
||||||
|
#ifdef U8G2_USE_DYNAMIC_ALLOC
|
||||||
|
*page_cnt = 4;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
static uint8_t buf[512];
|
||||||
|
*page_cnt = 4;
|
||||||
|
return buf;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
uint8_t *u8g2_m_16_8_1(uint8_t *page_cnt)
|
||||||
|
{
|
||||||
|
#ifdef U8G2_USE_DYNAMIC_ALLOC
|
||||||
|
*page_cnt = 1;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
static uint8_t buf[128];
|
||||||
|
*page_cnt = 1;
|
||||||
|
return buf;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
uint8_t *u8g2_m_16_8_2(uint8_t *page_cnt)
|
||||||
|
{
|
||||||
|
#ifdef U8G2_USE_DYNAMIC_ALLOC
|
||||||
|
*page_cnt = 2;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
static uint8_t buf[256];
|
||||||
|
*page_cnt = 2;
|
||||||
|
return buf;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
uint8_t *u8g2_m_16_8_f(uint8_t *page_cnt)
|
||||||
|
{
|
||||||
|
#ifdef U8G2_USE_DYNAMIC_ALLOC
|
||||||
|
*page_cnt = 8;
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
static uint8_t buf[1024];
|
||||||
|
*page_cnt = 8;
|
||||||
|
return buf;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* end of generated code */
|
||||||
88
main/utilities/u8g2/src/u8g2_d_setup.c
Normal file
88
main/utilities/u8g2/src/u8g2_d_setup.c
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/* u8g2_d_setup.c */
|
||||||
|
/* generated code, codebuild, u8g2 project */
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
/* ssd1306 */
|
||||||
|
/* ssd1306 1 */
|
||||||
|
void u8g2_Setup_ssd1306_i2c_128x32_univision_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
uint8_t tile_buf_height;
|
||||||
|
uint8_t *buf;
|
||||||
|
u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x32_univision, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb);
|
||||||
|
buf = u8g2_m_16_4_1(&tile_buf_height);
|
||||||
|
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
|
||||||
|
}
|
||||||
|
void u8g2_Setup_ssd1306_i2c_128x32_winstar_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
uint8_t tile_buf_height;
|
||||||
|
uint8_t *buf;
|
||||||
|
u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x32_winstar, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb);
|
||||||
|
buf = u8g2_m_16_4_1(&tile_buf_height);
|
||||||
|
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
|
||||||
|
}
|
||||||
|
/* ssd1306 2 */
|
||||||
|
void u8g2_Setup_ssd1306_i2c_128x32_univision_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
uint8_t tile_buf_height;
|
||||||
|
uint8_t *buf;
|
||||||
|
u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x32_univision, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb);
|
||||||
|
buf = u8g2_m_16_4_2(&tile_buf_height);
|
||||||
|
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
|
||||||
|
}
|
||||||
|
void u8g2_Setup_ssd1306_i2c_128x32_winstar_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
uint8_t tile_buf_height;
|
||||||
|
uint8_t *buf;
|
||||||
|
u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x32_winstar, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb);
|
||||||
|
buf = u8g2_m_16_4_2(&tile_buf_height);
|
||||||
|
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
|
||||||
|
}
|
||||||
|
/* ssd1306 f */
|
||||||
|
void u8g2_Setup_ssd1306_i2c_128x32_univision_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
uint8_t tile_buf_height;
|
||||||
|
uint8_t *buf;
|
||||||
|
u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x32_univision, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb);
|
||||||
|
buf = u8g2_m_16_4_f(&tile_buf_height);
|
||||||
|
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
|
||||||
|
}
|
||||||
|
void u8g2_Setup_ssd1306_i2c_128x32_winstar_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
uint8_t tile_buf_height;
|
||||||
|
uint8_t *buf;
|
||||||
|
u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x32_winstar, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb);
|
||||||
|
buf = u8g2_m_16_4_f(&tile_buf_height);
|
||||||
|
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ssd1306 */
|
||||||
|
/* ssd1306 1 */
|
||||||
|
void u8g2_Setup_ssd1306_i2c_128x64_noname_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
uint8_t tile_buf_height;
|
||||||
|
uint8_t *buf;
|
||||||
|
u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb);
|
||||||
|
buf = u8g2_m_16_8_1(&tile_buf_height);
|
||||||
|
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
|
||||||
|
}
|
||||||
|
/* ssd1306 2 */
|
||||||
|
void u8g2_Setup_ssd1306_i2c_128x64_noname_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
uint8_t tile_buf_height;
|
||||||
|
uint8_t *buf;
|
||||||
|
u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb);
|
||||||
|
buf = u8g2_m_16_8_2(&tile_buf_height);
|
||||||
|
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
|
||||||
|
}
|
||||||
|
/* ssd1306 f */
|
||||||
|
void u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
uint8_t tile_buf_height;
|
||||||
|
uint8_t *buf;
|
||||||
|
u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb);
|
||||||
|
buf = u8g2_m_16_8_f(&tile_buf_height);
|
||||||
|
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of generated code */
|
||||||
1563
main/utilities/u8g2/src/u8g2_font.c
Normal file
1563
main/utilities/u8g2/src/u8g2_font.c
Normal file
File diff suppressed because it is too large
Load Diff
431276
main/utilities/u8g2/src/u8g2_fonts.c
Normal file
431276
main/utilities/u8g2/src/u8g2_fonts.c
Normal file
File diff suppressed because it is too large
Load Diff
255
main/utilities/u8g2/src/u8g2_hvline.c
Normal file
255
main/utilities/u8g2/src/u8g2_hvline.c
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_hvline.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
Calltree
|
||||||
|
|
||||||
|
void u8g2_DrawHVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
u8g2->cb->draw_l90
|
||||||
|
u8g2_draw_hv_line_2dir
|
||||||
|
u8g2->ll_hvline(u8g2, x, y, len, dir);
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/*==========================================================*/
|
||||||
|
/* intersection procedure */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Description:
|
||||||
|
clip range from pos a (included) with line len (a+len excluded) agains c (included) to d (excluded)
|
||||||
|
Assumptions:
|
||||||
|
len > 0
|
||||||
|
c <= d (this is not checked)
|
||||||
|
will return 0 if there is no intersection and if a > b
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uint8_t u8g2_clip_intersection2(u8g2_uint_t *ap, u8g2_uint_t *len, u8g2_uint_t c, u8g2_uint_t d)
|
||||||
|
{
|
||||||
|
u8g2_uint_t a = *ap;
|
||||||
|
u8g2_uint_t b;
|
||||||
|
b = a;
|
||||||
|
b += *len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Description:
|
||||||
|
clip range from a (included) to b (excluded) agains c (included) to d (excluded)
|
||||||
|
Assumptions:
|
||||||
|
a <= b (violation is checked and handled correctly)
|
||||||
|
c <= d (this is not checked)
|
||||||
|
will return 0 if there is no intersection and if a > b
|
||||||
|
|
||||||
|
optimized clipping: c is set to 0 --> 27 Oct 2018: again removed the c==0 assumption
|
||||||
|
|
||||||
|
replaced by uint8_t u8g2_clip_intersection2
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* handle the a>b case correctly. If code and time is critical, this could */
|
||||||
|
/* be removed completly (be aware about memory curruption for wrong */
|
||||||
|
/* arguments) or return 0 for a>b (will lead to skipped lines for wrong */
|
||||||
|
/* arguments) */
|
||||||
|
|
||||||
|
/* removing the following if clause completly may lead to memory corruption of a>b */
|
||||||
|
if ( a > b )
|
||||||
|
{
|
||||||
|
/* replacing this if with a simple "return 0;" will not handle the case with negative a */
|
||||||
|
if ( a < d )
|
||||||
|
{
|
||||||
|
b = d;
|
||||||
|
b--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* from now on, the asumption a <= b is ok */
|
||||||
|
|
||||||
|
if ( a >= d )
|
||||||
|
return 0;
|
||||||
|
if ( b <= c )
|
||||||
|
return 0;
|
||||||
|
if ( a < c )
|
||||||
|
a = c;
|
||||||
|
if ( b > d )
|
||||||
|
b = d;
|
||||||
|
|
||||||
|
*ap = a;
|
||||||
|
b -= a;
|
||||||
|
*len = b;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*==========================================================*/
|
||||||
|
/* draw procedures */
|
||||||
|
|
||||||
|
/*
|
||||||
|
x,y Upper left position of the line within the pixel buffer
|
||||||
|
len length of the line in pixel, len must not be 0
|
||||||
|
dir 0: horizontal line (left to right)
|
||||||
|
1: vertical line (top to bottom)
|
||||||
|
This function first adjusts the y position to the local buffer. Then it
|
||||||
|
will clip the line and call u8g2_draw_low_level_hv_line()
|
||||||
|
|
||||||
|
*/
|
||||||
|
void u8g2_draw_hv_line_2dir(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* clipping happens before the display rotation */
|
||||||
|
|
||||||
|
/* transform to pixel buffer coordinates */
|
||||||
|
y -= u8g2->pixel_curr_row;
|
||||||
|
|
||||||
|
u8g2->ll_hvline(u8g2, x, y, len, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is the toplevel function for the hv line draw procedures.
|
||||||
|
This function should be called by the user.
|
||||||
|
|
||||||
|
"dir" may have 4 directions: 0 (left to right), 1, 2, 3 (down up)
|
||||||
|
*/
|
||||||
|
void u8g2_DrawHVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
/* Make a call to the callback function (e.g. u8g2_draw_l90_r0). */
|
||||||
|
/* The callback may rotate the hv line */
|
||||||
|
/* after rotation this will call u8g2_draw_hv_line_4dir() */
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
|
||||||
|
if ( u8g2->is_page_clip_window_intersection != 0 )
|
||||||
|
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
|
||||||
|
if ( len != 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
/* convert to two directions */
|
||||||
|
if ( len > 1 )
|
||||||
|
{
|
||||||
|
if ( dir == 2 )
|
||||||
|
{
|
||||||
|
x -= len;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
else if ( dir == 3 )
|
||||||
|
{
|
||||||
|
y -= len;
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dir &= 1;
|
||||||
|
|
||||||
|
/* clip against the user window */
|
||||||
|
if ( dir == 0 )
|
||||||
|
{
|
||||||
|
if ( y < u8g2->user_y0 )
|
||||||
|
return;
|
||||||
|
if ( y >= u8g2->user_y1 )
|
||||||
|
return;
|
||||||
|
if ( u8g2_clip_intersection2(&x, &len, u8g2->user_x0, u8g2->user_x1) == 0 )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( x < u8g2->user_x0 )
|
||||||
|
return;
|
||||||
|
if ( x >= u8g2->user_x1 )
|
||||||
|
return;
|
||||||
|
if ( u8g2_clip_intersection2(&y, &len, u8g2->user_y0, u8g2->user_y1) == 0 )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u8g2->cb->draw_l90(u8g2, x, y, len, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawHLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len)
|
||||||
|
{
|
||||||
|
// #ifdef U8G2_WITH_INTERSECTION
|
||||||
|
// if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )
|
||||||
|
// return;
|
||||||
|
// #endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len)
|
||||||
|
{
|
||||||
|
// #ifdef U8G2_WITH_INTERSECTION
|
||||||
|
// if ( u8g2_IsIntersection(u8g2, x, y, x+1, y+len) == 0 )
|
||||||
|
// return;
|
||||||
|
// #endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, len, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawPixel(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y)
|
||||||
|
{
|
||||||
|
#ifdef U8G2_WITH_INTERSECTION
|
||||||
|
if ( y < u8g2->user_y0 )
|
||||||
|
return;
|
||||||
|
if ( y >= u8g2->user_y1 )
|
||||||
|
return;
|
||||||
|
if ( x < u8g2->user_x0 )
|
||||||
|
return;
|
||||||
|
if ( x >= u8g2->user_x1 )
|
||||||
|
return;
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Assign the draw color for all drawing functions.
|
||||||
|
color may be 0 or 1. The actual color is defined by the display.
|
||||||
|
With color = 1 the drawing function will set the display memory to 1.
|
||||||
|
For OLEDs this ususally means, that the pixel is enabled and the LED
|
||||||
|
at the pixel is turned on.
|
||||||
|
On an LCD it usually means that the LCD segment of the pixel is enabled,
|
||||||
|
which absorbs the light.
|
||||||
|
For eInk/ePaper it means black ink.
|
||||||
|
|
||||||
|
7 Jan 2017: Allow color value 2 for XOR operation.
|
||||||
|
|
||||||
|
*/
|
||||||
|
void u8g2_SetDrawColor(u8g2_t *u8g2, uint8_t color)
|
||||||
|
{
|
||||||
|
u8g2->draw_color = color; /* u8g2_SetDrawColor: just assign the argument */
|
||||||
|
if ( color >= 3 )
|
||||||
|
u8g2->draw_color = 1; /* u8g2_SetDrawColor: make color as one if arg is invalid */
|
||||||
|
}
|
||||||
|
|
||||||
150
main/utilities/u8g2/src/u8g2_input_value.c
Normal file
150
main/utilities/u8g2/src/u8g2_input_value.c
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_input_value.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
return:
|
||||||
|
0: value is not changed (HOME/Break Button pressed)
|
||||||
|
1: value has been updated
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint8_t u8g2_UserInterfaceInputValue(u8g2_t *u8g2, const char *title, const char *pre, uint8_t *value, uint8_t lo, uint8_t hi, uint8_t digits, const char *post)
|
||||||
|
{
|
||||||
|
uint8_t line_height;
|
||||||
|
uint8_t height;
|
||||||
|
u8g2_uint_t pixel_height;
|
||||||
|
u8g2_uint_t y, yy;
|
||||||
|
u8g2_uint_t pixel_width;
|
||||||
|
u8g2_uint_t x, xx;
|
||||||
|
|
||||||
|
uint8_t local_value = *value;
|
||||||
|
//uint8_t r; /* not used ??? */
|
||||||
|
uint8_t event;
|
||||||
|
|
||||||
|
/* only horizontal strings are supported, so force this here */
|
||||||
|
u8g2_SetFontDirection(u8g2, 0);
|
||||||
|
|
||||||
|
/* force baseline position */
|
||||||
|
u8g2_SetFontPosBaseline(u8g2);
|
||||||
|
|
||||||
|
/* calculate line height */
|
||||||
|
line_height = u8g2_GetAscent(u8g2);
|
||||||
|
line_height -= u8g2_GetDescent(u8g2);
|
||||||
|
|
||||||
|
|
||||||
|
/* calculate overall height of the input value box */
|
||||||
|
height = 1; /* value input line */
|
||||||
|
height += u8x8_GetStringLineCnt(title);
|
||||||
|
|
||||||
|
/* calculate the height in pixel */
|
||||||
|
pixel_height = height;
|
||||||
|
pixel_height *= line_height;
|
||||||
|
|
||||||
|
|
||||||
|
/* calculate offset from top */
|
||||||
|
y = 0;
|
||||||
|
if ( pixel_height < u8g2_GetDisplayHeight(u8g2) )
|
||||||
|
{
|
||||||
|
y = u8g2_GetDisplayHeight(u8g2);
|
||||||
|
y -= pixel_height;
|
||||||
|
y /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate offset from left for the label */
|
||||||
|
x = 0;
|
||||||
|
pixel_width = u8g2_GetUTF8Width(u8g2, pre);
|
||||||
|
pixel_width += u8g2_GetUTF8Width(u8g2, "0") * digits;
|
||||||
|
pixel_width += u8g2_GetUTF8Width(u8g2, post);
|
||||||
|
if ( pixel_width < u8g2_GetDisplayWidth(u8g2) )
|
||||||
|
{
|
||||||
|
x = u8g2_GetDisplayWidth(u8g2);
|
||||||
|
x -= pixel_width;
|
||||||
|
x /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* event loop */
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
u8g2_FirstPage(u8g2);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* render */
|
||||||
|
yy = y;
|
||||||
|
yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title);
|
||||||
|
xx = x;
|
||||||
|
xx += u8g2_DrawUTF8(u8g2, xx, yy, pre);
|
||||||
|
xx += u8g2_DrawUTF8(u8g2, xx, yy, u8x8_u8toa(local_value, digits));
|
||||||
|
u8g2_DrawUTF8(u8g2, xx, yy, post);
|
||||||
|
} while( u8g2_NextPage(u8g2) );
|
||||||
|
|
||||||
|
#ifdef U8G2_REF_MAN_PIC
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2));
|
||||||
|
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
|
||||||
|
{
|
||||||
|
*value = local_value;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP )
|
||||||
|
{
|
||||||
|
if ( local_value >= hi )
|
||||||
|
local_value = lo;
|
||||||
|
else
|
||||||
|
local_value++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN )
|
||||||
|
{
|
||||||
|
if ( local_value <= lo )
|
||||||
|
local_value = hi;
|
||||||
|
else
|
||||||
|
local_value--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* never reached */
|
||||||
|
//return r;
|
||||||
|
}
|
||||||
176
main/utilities/u8g2/src/u8g2_intersection.c
Normal file
176
main/utilities/u8g2/src/u8g2_intersection.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_intersection.c
|
||||||
|
|
||||||
|
Intersection calculation, code taken from u8g_clip.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define U8G2_ALWAYS_INLINE __inline__ __attribute__((always_inline))
|
||||||
|
#else
|
||||||
|
#define U8G2_ALWAYS_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(U8G2_WITH_INTERSECTION) || defined(U8G2_WITH_CLIP_WINDOW_SUPPORT)
|
||||||
|
|
||||||
|
#ifdef OLD_VERSION_WITH_SYMETRIC_BOUNDARIES
|
||||||
|
|
||||||
|
/*
|
||||||
|
intersection assumptions:
|
||||||
|
a1 <= a2 is always true
|
||||||
|
|
||||||
|
minimized version
|
||||||
|
---1----0 1 b1 <= a2 && b1 > b2
|
||||||
|
-----1--0 1 b2 >= a1 && b1 > b2
|
||||||
|
---1-1--- 1 b1 <= a2 && b2 >= a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
calculate the intersection between a0/a1 and v0/v1
|
||||||
|
The intersection check returns one if the range of a0/a1 has an intersection with v0/v1.
|
||||||
|
The intersection check includes the boundary values v1 and a1.
|
||||||
|
|
||||||
|
The following asserts will succeed:
|
||||||
|
assert( u8g2_is_intersection_decision_tree(4, 6, 7, 9) == 0 );
|
||||||
|
assert( u8g2_is_intersection_decision_tree(4, 6, 6, 9) != 0 );
|
||||||
|
assert( u8g2_is_intersection_decision_tree(6, 9, 4, 6) != 0 );
|
||||||
|
assert( u8g2_is_intersection_decision_tree(7, 9, 4, 6) == 0 );
|
||||||
|
*/
|
||||||
|
|
||||||
|
//static uint8_t U8G2_ALWAYS_INLINE u8g2_is_intersection_decision_tree(u8g_uint_t a0, u8g_uint_t a1, u8g_uint_t v0, u8g_uint_t v1)
|
||||||
|
static uint8_t u8g2_is_intersection_decision_tree(u8g2_uint_t a0, u8g2_uint_t a1, u8g2_uint_t v0, u8g2_uint_t v1)
|
||||||
|
{
|
||||||
|
if ( v0 <= a1 )
|
||||||
|
{
|
||||||
|
if ( v1 >= a0 )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( v0 > v1 )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( v1 >= a0 )
|
||||||
|
{
|
||||||
|
if ( v0 > v1 )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* OLD_VERSION_WITH_SYMETRIC_BOUNDARIES */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
version with asymetric boundaries.
|
||||||
|
a1 and v1 are excluded
|
||||||
|
v0 == v1 is not support end return 1
|
||||||
|
*/
|
||||||
|
uint8_t u8g2_is_intersection_decision_tree(u8g2_uint_t a0, u8g2_uint_t a1, u8g2_uint_t v0, u8g2_uint_t v1)
|
||||||
|
{
|
||||||
|
if ( v0 < a1 ) // v0 <= a1
|
||||||
|
{
|
||||||
|
if ( v1 > a0 ) // v1 >= a0
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( v0 > v1 ) // v0 > v1
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( v1 > a0 ) // v1 >= a0
|
||||||
|
{
|
||||||
|
if ( v0 > v1 ) // v0 > v1
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* upper limits are not included (asymetric boundaries) */
|
||||||
|
uint8_t u8g2_IsIntersection(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1)
|
||||||
|
{
|
||||||
|
if ( u8g2_is_intersection_decision_tree(u8g2->user_y0, u8g2->user_y1, y0, y1) == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return u8g2_is_intersection_decision_tree(u8g2->user_x0, u8g2->user_x1, x0, x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* U8G2_WITH_INTERSECTION */
|
||||||
|
|
||||||
94
main/utilities/u8g2/src/u8g2_kerning.c
Normal file
94
main/utilities/u8g2/src/u8g2_kerning.c
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_kerning.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
/* this function is used as "u8g2_get_kerning_cb" */
|
||||||
|
/*
|
||||||
|
uint8_t u8g2_GetNullKerning(u8g2_t *u8g2, uint16_t e1, uint16_t e2)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* this function is used as "u8g2_get_kerning_cb" */
|
||||||
|
uint8_t u8g2_GetKerning(U8X8_UNUSED u8g2_t *u8g2, u8g2_kerning_t *kerning, uint16_t e1, uint16_t e2)
|
||||||
|
{
|
||||||
|
uint16_t i1, i2, cnt, end;
|
||||||
|
if ( kerning == NULL )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* search for the encoding in the first table */
|
||||||
|
cnt = kerning->first_table_cnt;
|
||||||
|
cnt--; /* ignore the last element of the table, which is 0x0ffff */
|
||||||
|
for( i1 = 0; i1 < cnt; i1++ )
|
||||||
|
{
|
||||||
|
if ( kerning->first_encoding_table[i1] == e1 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( i1 >= cnt )
|
||||||
|
return 0; /* e1 not part of the kerning table, return 0 */
|
||||||
|
|
||||||
|
/* get the upper index for i2 */
|
||||||
|
end = kerning->index_to_second_table[i1+1];
|
||||||
|
for( i2 = kerning->index_to_second_table[i1]; i2 < end; i2++ )
|
||||||
|
{
|
||||||
|
if ( kerning->second_encoding_table[i2] == e2 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( i2 >= end )
|
||||||
|
return 0; /* e2 not part of any pair with e1, return 0 */
|
||||||
|
|
||||||
|
return kerning->kerning_values[i2];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8g2_GetKerningByTable(U8X8_UNUSED u8g2_t *u8g2, const uint16_t *kt, uint16_t e1, uint16_t e2)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
i = 0;
|
||||||
|
if ( kt == NULL )
|
||||||
|
return 0;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if ( kt[i] == 0x0ffff )
|
||||||
|
break;
|
||||||
|
if ( kt[i] == e1 && kt[i+1] == e2 )
|
||||||
|
return kt[i+2];
|
||||||
|
i+=3;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
92
main/utilities/u8g2/src/u8g2_line.c
Normal file
92
main/utilities/u8g2/src/u8g2_line.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_box.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_DrawLine(u8g2_t *u8g2, u8g2_uint_t x1, u8g2_uint_t y1, u8g2_uint_t x2, u8g2_uint_t y2)
|
||||||
|
{
|
||||||
|
u8g2_uint_t tmp;
|
||||||
|
u8g2_uint_t x,y;
|
||||||
|
u8g2_uint_t dx, dy;
|
||||||
|
u8g2_int_t err;
|
||||||
|
u8g2_int_t ystep;
|
||||||
|
|
||||||
|
uint8_t swapxy = 0;
|
||||||
|
|
||||||
|
/* no intersection check at the moment, should be added... */
|
||||||
|
|
||||||
|
if ( x1 > x2 ) dx = x1-x2; else dx = x2-x1;
|
||||||
|
if ( y1 > y2 ) dy = y1-y2; else dy = y2-y1;
|
||||||
|
|
||||||
|
if ( dy > dx )
|
||||||
|
{
|
||||||
|
swapxy = 1;
|
||||||
|
tmp = dx; dx =dy; dy = tmp;
|
||||||
|
tmp = x1; x1 =y1; y1 = tmp;
|
||||||
|
tmp = x2; x2 =y2; y2 = tmp;
|
||||||
|
}
|
||||||
|
if ( x1 > x2 )
|
||||||
|
{
|
||||||
|
tmp = x1; x1 =x2; x2 = tmp;
|
||||||
|
tmp = y1; y1 =y2; y2 = tmp;
|
||||||
|
}
|
||||||
|
err = dx >> 1;
|
||||||
|
if ( y2 > y1 ) ystep = 1; else ystep = -1;
|
||||||
|
y = y1;
|
||||||
|
|
||||||
|
#ifndef U8G2_16BIT
|
||||||
|
if ( x2 == 255 )
|
||||||
|
x2--;
|
||||||
|
#else
|
||||||
|
if ( x2 == 0xffff )
|
||||||
|
x2--;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( x = x1; x <= x2; x++ )
|
||||||
|
{
|
||||||
|
if ( swapxy == 0 )
|
||||||
|
u8g2_DrawPixel(u8g2, x, y);
|
||||||
|
else
|
||||||
|
u8g2_DrawPixel(u8g2, y, x);
|
||||||
|
err -= (u8g2_uint_t)dy;
|
||||||
|
if ( err < 0 )
|
||||||
|
{
|
||||||
|
y += (u8g2_uint_t)ystep;
|
||||||
|
err += (u8g2_uint_t)dx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
371
main/utilities/u8g2/src/u8g2_ll_hvline.c
Normal file
371
main/utilities/u8g2/src/u8g2_ll_hvline.c
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_ll_hvline.c
|
||||||
|
|
||||||
|
low level hvline
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
*ptr |= or_mask
|
||||||
|
*ptr ^= xor_mask
|
||||||
|
|
||||||
|
color = 0: or_mask = 1, xor_mask = 1
|
||||||
|
color = 1: or_mask = 1, xor_mask = 0
|
||||||
|
color = 2: or_mask = 0, xor_mask = 1
|
||||||
|
|
||||||
|
if ( color <= 1 )
|
||||||
|
or_mask = mask;
|
||||||
|
if ( color != 1 )
|
||||||
|
xor_mask = mask;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/*=================================================*/
|
||||||
|
/*
|
||||||
|
u8g2_ll_hvline_vertical_top_lsb
|
||||||
|
SSD13xx
|
||||||
|
UC1701
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_HVLINE_SPEED_OPTIMIZATION
|
||||||
|
|
||||||
|
/*
|
||||||
|
x,y Upper left position of the line within the local buffer (not the display!)
|
||||||
|
len length of the line in pixel, len must not be 0
|
||||||
|
dir 0: horizontal line (left to right)
|
||||||
|
1: vertical line (top to bottom)
|
||||||
|
asumption:
|
||||||
|
all clipping done
|
||||||
|
*/
|
||||||
|
void u8g2_ll_hvline_vertical_top_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
uint16_t offset;
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint8_t bit_pos, mask;
|
||||||
|
uint8_t or_mask, xor_mask;
|
||||||
|
#ifdef __unix
|
||||||
|
uint8_t *max_ptr = u8g2->tile_buf_ptr + u8g2_GetU8x8(u8g2)->display_info->tile_width*u8g2->tile_buf_height*8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//assert(x >= u8g2->buf_x0);
|
||||||
|
//assert(x < u8g2_GetU8x8(u8g2)->display_info->tile_width*8);
|
||||||
|
//assert(y >= u8g2->buf_y0);
|
||||||
|
//assert(y < u8g2_GetU8x8(u8g2)->display_info->tile_height*8);
|
||||||
|
|
||||||
|
/* bytes are vertical, lsb on top (y=0), msb at bottom (y=7) */
|
||||||
|
bit_pos = y; /* overflow truncate is ok here... */
|
||||||
|
bit_pos &= 7; /* ... because only the lowest 3 bits are needed */
|
||||||
|
mask = 1;
|
||||||
|
mask <<= bit_pos;
|
||||||
|
|
||||||
|
or_mask = 0;
|
||||||
|
xor_mask = 0;
|
||||||
|
if ( u8g2->draw_color <= 1 )
|
||||||
|
or_mask = mask;
|
||||||
|
if ( u8g2->draw_color != 1 )
|
||||||
|
xor_mask = mask;
|
||||||
|
|
||||||
|
|
||||||
|
offset = y; /* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */
|
||||||
|
offset &= ~7;
|
||||||
|
offset *= u8g2_GetU8x8(u8g2)->display_info->tile_width;
|
||||||
|
ptr = u8g2->tile_buf_ptr;
|
||||||
|
ptr += offset;
|
||||||
|
ptr += x;
|
||||||
|
|
||||||
|
if ( dir == 0 )
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#ifdef __unix
|
||||||
|
assert(ptr < max_ptr);
|
||||||
|
#endif
|
||||||
|
*ptr |= or_mask;
|
||||||
|
*ptr ^= xor_mask;
|
||||||
|
ptr++;
|
||||||
|
len--;
|
||||||
|
} while( len != 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#ifdef __unix
|
||||||
|
assert(ptr < max_ptr);
|
||||||
|
#endif
|
||||||
|
*ptr |= or_mask;
|
||||||
|
*ptr ^= xor_mask;
|
||||||
|
|
||||||
|
bit_pos++;
|
||||||
|
bit_pos &= 7;
|
||||||
|
|
||||||
|
len--;
|
||||||
|
|
||||||
|
if ( bit_pos == 0 )
|
||||||
|
{
|
||||||
|
ptr+=u8g2->pixel_buf_width; /* 6 Jan 17: Changed u8g2->width to u8g2->pixel_buf_width, issue #148 */
|
||||||
|
|
||||||
|
if ( u8g2->draw_color <= 1 )
|
||||||
|
or_mask = 1;
|
||||||
|
if ( u8g2->draw_color != 1 )
|
||||||
|
xor_mask = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
or_mask <<= 1;
|
||||||
|
xor_mask <<= 1;
|
||||||
|
}
|
||||||
|
} while( len != 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#else /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */
|
||||||
|
|
||||||
|
/*
|
||||||
|
x,y position within the buffer
|
||||||
|
*/
|
||||||
|
static void u8g2_draw_pixel_vertical_top_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y)
|
||||||
|
{
|
||||||
|
uint16_t offset;
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint8_t bit_pos, mask;
|
||||||
|
|
||||||
|
//assert(x >= u8g2->buf_x0);
|
||||||
|
//assert(x < u8g2_GetU8x8(u8g2)->display_info->tile_width*8);
|
||||||
|
//assert(y >= u8g2->buf_y0);
|
||||||
|
//assert(y < u8g2_GetU8x8(u8g2)->display_info->tile_height*8);
|
||||||
|
|
||||||
|
/* bytes are vertical, lsb on top (y=0), msb at bottom (y=7) */
|
||||||
|
bit_pos = y; /* overflow truncate is ok here... */
|
||||||
|
bit_pos &= 7; /* ... because only the lowest 3 bits are needed */
|
||||||
|
mask = 1;
|
||||||
|
mask <<= bit_pos;
|
||||||
|
|
||||||
|
offset = y; /* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */
|
||||||
|
offset &= ~7;
|
||||||
|
offset *= u8g2_GetU8x8(u8g2)->display_info->tile_width;
|
||||||
|
ptr = u8g2->tile_buf_ptr;
|
||||||
|
ptr += offset;
|
||||||
|
ptr += x;
|
||||||
|
|
||||||
|
|
||||||
|
if ( u8g2->draw_color <= 1 )
|
||||||
|
*ptr |= mask;
|
||||||
|
if ( u8g2->draw_color != 1 )
|
||||||
|
*ptr ^= mask;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
x,y Upper left position of the line within the local buffer (not the display!)
|
||||||
|
len length of the line in pixel, len must not be 0
|
||||||
|
dir 0: horizontal line (left to right)
|
||||||
|
1: vertical line (top to bottom)
|
||||||
|
asumption:
|
||||||
|
all clipping done
|
||||||
|
*/
|
||||||
|
void u8g2_ll_hvline_vertical_top_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
if ( dir == 0 )
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8g2_draw_pixel_vertical_top_lsb(u8g2, x, y);
|
||||||
|
x++;
|
||||||
|
len--;
|
||||||
|
} while( len != 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8g2_draw_pixel_vertical_top_lsb(u8g2, x, y);
|
||||||
|
y++;
|
||||||
|
len--;
|
||||||
|
} while( len != 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */
|
||||||
|
|
||||||
|
/*=================================================*/
|
||||||
|
/*
|
||||||
|
u8g2_ll_hvline_horizontal_right_lsb
|
||||||
|
ST7920
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_HVLINE_SPEED_OPTIMIZATION
|
||||||
|
|
||||||
|
/*
|
||||||
|
x,y Upper left position of the line within the local buffer (not the display!)
|
||||||
|
len length of the line in pixel, len must not be 0
|
||||||
|
dir 0: horizontal line (left to right)
|
||||||
|
1: vertical line (top to bottom)
|
||||||
|
asumption:
|
||||||
|
all clipping done
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* SH1122, LD7032, ST7920, ST7986, LC7981, T6963, SED1330, RA8835, MAX7219, LS0 */
|
||||||
|
void u8g2_ll_hvline_horizontal_right_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
uint16_t offset;
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint8_t bit_pos;
|
||||||
|
uint8_t mask;
|
||||||
|
uint8_t tile_width = u8g2_GetU8x8(u8g2)->display_info->tile_width;
|
||||||
|
|
||||||
|
bit_pos = x; /* overflow truncate is ok here... */
|
||||||
|
bit_pos &= 7; /* ... because only the lowest 3 bits are needed */
|
||||||
|
mask = 128;
|
||||||
|
mask >>= bit_pos;
|
||||||
|
|
||||||
|
offset = y; /* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */
|
||||||
|
offset *= tile_width;
|
||||||
|
offset += x>>3;
|
||||||
|
ptr = u8g2->tile_buf_ptr;
|
||||||
|
ptr += offset;
|
||||||
|
|
||||||
|
if ( dir == 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( u8g2->draw_color <= 1 )
|
||||||
|
*ptr |= mask;
|
||||||
|
if ( u8g2->draw_color != 1 )
|
||||||
|
*ptr ^= mask;
|
||||||
|
|
||||||
|
mask >>= 1;
|
||||||
|
if ( mask == 0 )
|
||||||
|
{
|
||||||
|
mask = 128;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//x++;
|
||||||
|
len--;
|
||||||
|
} while( len != 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ( u8g2->draw_color <= 1 )
|
||||||
|
*ptr |= mask;
|
||||||
|
if ( u8g2->draw_color != 1 )
|
||||||
|
*ptr ^= mask;
|
||||||
|
|
||||||
|
ptr += tile_width;
|
||||||
|
//y++;
|
||||||
|
len--;
|
||||||
|
} while( len != 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
x,y position within the buffer
|
||||||
|
*/
|
||||||
|
/* SH1122, LD7032, ST7920, ST7986, LC7981, T6963, SED1330, RA8835, MAX7219, LS0 */
|
||||||
|
static void u8g2_draw_pixel_horizontal_right_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y)
|
||||||
|
{
|
||||||
|
uint16_t offset;
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint8_t bit_pos, mask;
|
||||||
|
|
||||||
|
//assert(x >= u8g2->buf_x0);
|
||||||
|
//assert(x < u8g2_GetU8x8(u8g2)->display_info->tile_width*8);
|
||||||
|
//assert(y >= u8g2->buf_y0);
|
||||||
|
//assert(y < u8g2_GetU8x8(u8g2)->display_info->tile_height*8);
|
||||||
|
|
||||||
|
/* bytes are vertical, lsb on top (y=0), msb at bottom (y=7) */
|
||||||
|
bit_pos = x; /* overflow truncate is ok here... */
|
||||||
|
bit_pos &= 7; /* ... because only the lowest 3 bits are needed */
|
||||||
|
mask = 128;
|
||||||
|
mask >>= bit_pos;
|
||||||
|
x >>= 3;
|
||||||
|
|
||||||
|
offset = y; /* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */
|
||||||
|
offset *= u8g2_GetU8x8(u8g2)->display_info->tile_width;
|
||||||
|
offset += x;
|
||||||
|
ptr = u8g2->tile_buf_ptr;
|
||||||
|
ptr += offset;
|
||||||
|
|
||||||
|
|
||||||
|
if ( u8g2->draw_color <= 1 )
|
||||||
|
*ptr |= mask;
|
||||||
|
if ( u8g2->draw_color != 1 )
|
||||||
|
*ptr ^= mask;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
x,y Upper left position of the line within the local buffer (not the display!)
|
||||||
|
len length of the line in pixel, len must not be 0
|
||||||
|
dir 0: horizontal line (left to right)
|
||||||
|
1: vertical line (top to bottom)
|
||||||
|
asumption:
|
||||||
|
all clipping done
|
||||||
|
*/
|
||||||
|
/* SH1122, LD7032, ST7920, ST7986, LC7981, T6963, SED1330, RA8835, MAX7219, LS0 */
|
||||||
|
void u8g2_ll_hvline_horizontal_right_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
if ( dir == 0 )
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8g2_draw_pixel_horizontal_right_lsb(u8g2, x, y);
|
||||||
|
x++;
|
||||||
|
len--;
|
||||||
|
} while( len != 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8g2_draw_pixel_horizontal_right_lsb(u8g2, x, y);
|
||||||
|
y++;
|
||||||
|
len--;
|
||||||
|
} while( len != 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */
|
||||||
197
main/utilities/u8g2/src/u8g2_message.c
Normal file
197
main/utilities/u8g2/src/u8g2_message.c
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_message.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
#define SPACE_BETWEEN_BUTTONS_IN_PIXEL 6
|
||||||
|
#define SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL 3
|
||||||
|
|
||||||
|
uint8_t u8g2_draw_button_line(u8g2_t *u8g2, u8g2_uint_t y, u8g2_uint_t w, uint8_t cursor, const char *s)
|
||||||
|
{
|
||||||
|
u8g2_uint_t button_line_width;
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t cnt;
|
||||||
|
uint8_t is_invert;
|
||||||
|
|
||||||
|
u8g2_uint_t d;
|
||||||
|
u8g2_uint_t x;
|
||||||
|
|
||||||
|
cnt = u8x8_GetStringLineCnt(s);
|
||||||
|
|
||||||
|
|
||||||
|
/* calculate the width of the button line */
|
||||||
|
button_line_width = 0;
|
||||||
|
for( i = 0; i < cnt; i++ )
|
||||||
|
{
|
||||||
|
button_line_width += u8g2_GetUTF8Width(u8g2, u8x8_GetStringLineStart(i, s));
|
||||||
|
}
|
||||||
|
button_line_width += (cnt-1)*SPACE_BETWEEN_BUTTONS_IN_PIXEL; /* add some space between the buttons */
|
||||||
|
|
||||||
|
/* calculate the left offset */
|
||||||
|
d = 0;
|
||||||
|
if ( button_line_width < w )
|
||||||
|
{
|
||||||
|
d = w;
|
||||||
|
d -= button_line_width;
|
||||||
|
d /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draw the buttons */
|
||||||
|
x = d;
|
||||||
|
for( i = 0; i < cnt; i++ )
|
||||||
|
{
|
||||||
|
is_invert = 0;
|
||||||
|
if ( i == cursor )
|
||||||
|
is_invert = 1;
|
||||||
|
|
||||||
|
u8g2_DrawUTF8Line(u8g2, x, y, 0, u8x8_GetStringLineStart(i, s), 1, is_invert);
|
||||||
|
x += u8g2_GetUTF8Width(u8g2, u8x8_GetStringLineStart(i, s));
|
||||||
|
x += SPACE_BETWEEN_BUTTONS_IN_PIXEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the number of buttons */
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
title1: Multiple lines,separated by '\n'
|
||||||
|
title2: A single line/string which is terminated by '\0' or '\n' . "title2" accepts the return value from u8x8_GetStringLineStart()
|
||||||
|
title3: Multiple lines,separated by '\n'
|
||||||
|
buttons: one more more buttons separated by '\n' and terminated with '\0'
|
||||||
|
side effects:
|
||||||
|
u8g2_SetFontDirection(u8g2, 0);
|
||||||
|
u8g2_SetFontPosBaseline(u8g2);
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint8_t u8g2_UserInterfaceMessage(u8g2_t *u8g2, const char *title1, const char *title2, const char *title3, const char *buttons)
|
||||||
|
{
|
||||||
|
uint8_t height;
|
||||||
|
uint8_t line_height;
|
||||||
|
u8g2_uint_t pixel_height;
|
||||||
|
u8g2_uint_t y, yy;
|
||||||
|
|
||||||
|
uint8_t cursor = 0;
|
||||||
|
uint8_t button_cnt;
|
||||||
|
uint8_t event;
|
||||||
|
|
||||||
|
/* only horizontal strings are supported, so force this here */
|
||||||
|
u8g2_SetFontDirection(u8g2, 0);
|
||||||
|
|
||||||
|
/* force baseline position */
|
||||||
|
u8g2_SetFontPosBaseline(u8g2);
|
||||||
|
|
||||||
|
|
||||||
|
/* calculate line height */
|
||||||
|
line_height = u8g2_GetAscent(u8g2);
|
||||||
|
line_height -= u8g2_GetDescent(u8g2);
|
||||||
|
|
||||||
|
/* calculate overall height of the message box in lines*/
|
||||||
|
height = 1; /* button line */
|
||||||
|
height += u8x8_GetStringLineCnt(title1);
|
||||||
|
if ( title2 != NULL )
|
||||||
|
height++;
|
||||||
|
height += u8x8_GetStringLineCnt(title3);
|
||||||
|
|
||||||
|
/* calculate the height in pixel */
|
||||||
|
pixel_height = height;
|
||||||
|
pixel_height *= line_height;
|
||||||
|
|
||||||
|
/* ... and add the space between the text and the buttons */
|
||||||
|
pixel_height +=SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL;
|
||||||
|
|
||||||
|
/* calculate offset from top */
|
||||||
|
y = 0;
|
||||||
|
if ( pixel_height < u8g2_GetDisplayHeight(u8g2) )
|
||||||
|
{
|
||||||
|
y = u8g2_GetDisplayHeight(u8g2);
|
||||||
|
y -= pixel_height;
|
||||||
|
y /= 2;
|
||||||
|
}
|
||||||
|
y += u8g2_GetAscent(u8g2);
|
||||||
|
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
u8g2_FirstPage(u8g2);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
yy = y;
|
||||||
|
/* draw message box */
|
||||||
|
|
||||||
|
yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title1);
|
||||||
|
if ( title2 != NULL )
|
||||||
|
{
|
||||||
|
u8g2_DrawUTF8Line(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), title2, 0, 0);
|
||||||
|
yy+=line_height;
|
||||||
|
}
|
||||||
|
yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title3);
|
||||||
|
yy += SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL;
|
||||||
|
|
||||||
|
button_cnt = u8g2_draw_button_line(u8g2, yy, u8g2_GetDisplayWidth(u8g2), cursor, buttons);
|
||||||
|
|
||||||
|
} while( u8g2_NextPage(u8g2) );
|
||||||
|
|
||||||
|
#ifdef U8G2_REF_MAN_PIC
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2));
|
||||||
|
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
|
||||||
|
return cursor+1;
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
|
||||||
|
return 0;
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN )
|
||||||
|
{
|
||||||
|
cursor++;
|
||||||
|
if ( cursor >= button_cnt )
|
||||||
|
cursor = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP )
|
||||||
|
{
|
||||||
|
if ( cursor == 0 )
|
||||||
|
cursor = button_cnt;
|
||||||
|
cursor--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* never reached */
|
||||||
|
//return 0;
|
||||||
|
}
|
||||||
|
|
||||||
346
main/utilities/u8g2/src/u8g2_polygon.c
Normal file
346
main/utilities/u8g2/src/u8g2_polygon.c
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g22_polygon.c
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================*/
|
||||||
|
/* local definitions */
|
||||||
|
|
||||||
|
typedef int16_t pg_word_t;
|
||||||
|
|
||||||
|
|
||||||
|
struct pg_point_struct
|
||||||
|
{
|
||||||
|
pg_word_t x;
|
||||||
|
pg_word_t y;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _pg_struct pg_struct; /* forward declaration */
|
||||||
|
|
||||||
|
struct pg_edge_struct
|
||||||
|
{
|
||||||
|
pg_word_t x_direction; /* 1, if x2 is greater than x1, -1 otherwise */
|
||||||
|
pg_word_t height;
|
||||||
|
pg_word_t current_x_offset;
|
||||||
|
pg_word_t error_offset;
|
||||||
|
|
||||||
|
/* --- line loop --- */
|
||||||
|
pg_word_t current_y;
|
||||||
|
pg_word_t max_y;
|
||||||
|
pg_word_t current_x;
|
||||||
|
pg_word_t error;
|
||||||
|
|
||||||
|
/* --- outer loop --- */
|
||||||
|
uint8_t (*next_idx_fn)(pg_struct *pg, uint8_t i);
|
||||||
|
uint8_t curr_idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* maximum number of points in the polygon */
|
||||||
|
/* can be redefined, but highest possible value is 254 */
|
||||||
|
#define PG_MAX_POINTS 6
|
||||||
|
|
||||||
|
/* index numbers for the pge structures below */
|
||||||
|
#define PG_LEFT 0
|
||||||
|
#define PG_RIGHT 1
|
||||||
|
|
||||||
|
|
||||||
|
struct _pg_struct
|
||||||
|
{
|
||||||
|
struct pg_point_struct list[PG_MAX_POINTS];
|
||||||
|
uint8_t cnt;
|
||||||
|
uint8_t is_min_y_not_flat;
|
||||||
|
pg_word_t total_scan_line_cnt;
|
||||||
|
struct pg_edge_struct pge[2]; /* left and right line draw structures */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================*/
|
||||||
|
/* procedures, which should not be inlined (save as much flash ROM as possible */
|
||||||
|
|
||||||
|
#define PG_NOINLINE U8G2_NOINLINE
|
||||||
|
|
||||||
|
static uint8_t pge_Next(struct pg_edge_struct *pge) PG_NOINLINE;
|
||||||
|
static uint8_t pg_inc(pg_struct *pg, uint8_t i) PG_NOINLINE;
|
||||||
|
static uint8_t pg_dec(pg_struct *pg, uint8_t i) PG_NOINLINE;
|
||||||
|
static void pg_expand_min_y(pg_struct *pg, pg_word_t min_y, uint8_t pge_idx) PG_NOINLINE;
|
||||||
|
static void pg_line_init(pg_struct * const pg, uint8_t pge_index) PG_NOINLINE;
|
||||||
|
|
||||||
|
/*===========================================*/
|
||||||
|
/* line draw algorithm */
|
||||||
|
|
||||||
|
static uint8_t pge_Next(struct pg_edge_struct *pge)
|
||||||
|
{
|
||||||
|
if ( pge->current_y >= pge->max_y )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pge->current_x += pge->current_x_offset;
|
||||||
|
pge->error += pge->error_offset;
|
||||||
|
if ( pge->error > 0 )
|
||||||
|
{
|
||||||
|
pge->current_x += pge->x_direction;
|
||||||
|
pge->error -= pge->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
pge->current_y++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* assumes y2 > y1 */
|
||||||
|
static void pge_Init(struct pg_edge_struct *pge, pg_word_t x1, pg_word_t y1, pg_word_t x2, pg_word_t y2)
|
||||||
|
{
|
||||||
|
pg_word_t dx = x2 - x1;
|
||||||
|
pg_word_t width;
|
||||||
|
|
||||||
|
pge->height = y2 - y1;
|
||||||
|
pge->max_y = y2;
|
||||||
|
pge->current_y = y1;
|
||||||
|
pge->current_x = x1;
|
||||||
|
|
||||||
|
if ( dx >= 0 )
|
||||||
|
{
|
||||||
|
pge->x_direction = 1;
|
||||||
|
width = dx;
|
||||||
|
pge->error = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pge->x_direction = -1;
|
||||||
|
width = -dx;
|
||||||
|
pge->error = 1 - pge->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
pge->current_x_offset = dx / pge->height;
|
||||||
|
pge->error_offset = width % pge->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================*/
|
||||||
|
/* convex polygon algorithm */
|
||||||
|
|
||||||
|
static uint8_t pg_inc(pg_struct *pg, uint8_t i)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
if ( i >= pg->cnt )
|
||||||
|
i = 0;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t pg_dec(pg_struct *pg, uint8_t i)
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
if ( i >= pg->cnt )
|
||||||
|
i = pg->cnt-1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pg_expand_min_y(pg_struct *pg, pg_word_t min_y, uint8_t pge_idx)
|
||||||
|
{
|
||||||
|
uint8_t i = pg->pge[pge_idx].curr_idx;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
i = pg->pge[pge_idx].next_idx_fn(pg, i);
|
||||||
|
if ( pg->list[i].y != min_y )
|
||||||
|
break;
|
||||||
|
pg->pge[pge_idx].curr_idx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t pg_prepare(pg_struct *pg)
|
||||||
|
{
|
||||||
|
pg_word_t max_y;
|
||||||
|
pg_word_t min_y;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
/* setup the next index procedures */
|
||||||
|
pg->pge[PG_RIGHT].next_idx_fn = pg_inc;
|
||||||
|
pg->pge[PG_LEFT].next_idx_fn = pg_dec;
|
||||||
|
|
||||||
|
/* search for highest and lowest point */
|
||||||
|
max_y = pg->list[0].y;
|
||||||
|
min_y = pg->list[0].y;
|
||||||
|
pg->pge[PG_LEFT].curr_idx = 0;
|
||||||
|
for( i = 1; i < pg->cnt; i++ )
|
||||||
|
{
|
||||||
|
if ( max_y < pg->list[i].y )
|
||||||
|
{
|
||||||
|
max_y = pg->list[i].y;
|
||||||
|
}
|
||||||
|
if ( min_y > pg->list[i].y )
|
||||||
|
{
|
||||||
|
pg->pge[PG_LEFT].curr_idx = i;
|
||||||
|
min_y = pg->list[i].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate total number of scan lines */
|
||||||
|
pg->total_scan_line_cnt = max_y;
|
||||||
|
pg->total_scan_line_cnt -= min_y;
|
||||||
|
|
||||||
|
/* exit if polygon height is zero */
|
||||||
|
if ( pg->total_scan_line_cnt == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* if the minimum y side is flat, try to find the lowest and highest x points */
|
||||||
|
pg->pge[PG_RIGHT].curr_idx = pg->pge[PG_LEFT].curr_idx;
|
||||||
|
pg_expand_min_y(pg, min_y, PG_RIGHT);
|
||||||
|
pg_expand_min_y(pg, min_y, PG_LEFT);
|
||||||
|
|
||||||
|
/* check if the min side is really flat (depends on the x values) */
|
||||||
|
pg->is_min_y_not_flat = 1;
|
||||||
|
if ( pg->list[pg->pge[PG_LEFT].curr_idx].x != pg->list[pg->pge[PG_RIGHT].curr_idx].x )
|
||||||
|
{
|
||||||
|
pg->is_min_y_not_flat = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pg->total_scan_line_cnt--;
|
||||||
|
if ( pg->total_scan_line_cnt == 0 )
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pg_hline(pg_struct *pg, u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
pg_word_t x1, x2, y;
|
||||||
|
x1 = pg->pge[PG_LEFT].current_x;
|
||||||
|
x2 = pg->pge[PG_RIGHT].current_x;
|
||||||
|
y = pg->pge[PG_RIGHT].current_y;
|
||||||
|
|
||||||
|
if ( y < 0 )
|
||||||
|
return;
|
||||||
|
if ( y >= (pg_word_t)u8g2_GetDisplayHeight(u8g2) ) // does not work for 256x64 display???
|
||||||
|
return;
|
||||||
|
if ( x1 < x2 )
|
||||||
|
{
|
||||||
|
if ( x2 < 0 )
|
||||||
|
return;
|
||||||
|
if ( x1 >= (pg_word_t)u8g2_GetDisplayWidth(u8g2) )
|
||||||
|
return;
|
||||||
|
if ( x1 < 0 )
|
||||||
|
x1 = 0;
|
||||||
|
if ( x2 >= (pg_word_t)u8g2_GetDisplayWidth(u8g2) )
|
||||||
|
x2 = u8g2_GetDisplayWidth(u8g2);
|
||||||
|
u8g2_DrawHLine(u8g2, x1, y, x2 - x1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( x1 < 0 )
|
||||||
|
return;
|
||||||
|
if ( x2 >= (pg_word_t)u8g2_GetDisplayWidth(u8g2) )
|
||||||
|
return;
|
||||||
|
if ( x2 < 0 )
|
||||||
|
x1 = 0;
|
||||||
|
if ( x1 >= (pg_word_t)u8g2_GetDisplayWidth(u8g2) )
|
||||||
|
x1 = u8g2_GetDisplayWidth(u8g2);
|
||||||
|
u8g2_DrawHLine(u8g2, x2, y, x1 - x2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pg_line_init(pg_struct * const pg, uint8_t pge_index)
|
||||||
|
{
|
||||||
|
struct pg_edge_struct *pge = pg->pge+pge_index;
|
||||||
|
uint8_t idx;
|
||||||
|
pg_word_t x1;
|
||||||
|
pg_word_t y1;
|
||||||
|
pg_word_t x2;
|
||||||
|
pg_word_t y2;
|
||||||
|
|
||||||
|
idx = pge->curr_idx;
|
||||||
|
y1 = pg->list[idx].y;
|
||||||
|
x1 = pg->list[idx].x;
|
||||||
|
idx = pge->next_idx_fn(pg, idx);
|
||||||
|
y2 = pg->list[idx].y;
|
||||||
|
x2 = pg->list[idx].x;
|
||||||
|
pge->curr_idx = idx;
|
||||||
|
|
||||||
|
pge_Init(pge, x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pg_exec(pg_struct *pg, u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
pg_word_t i = pg->total_scan_line_cnt;
|
||||||
|
|
||||||
|
/* first line is skipped if the min y line is not flat */
|
||||||
|
pg_line_init(pg, PG_LEFT);
|
||||||
|
pg_line_init(pg, PG_RIGHT);
|
||||||
|
|
||||||
|
if ( pg->is_min_y_not_flat != 0 )
|
||||||
|
{
|
||||||
|
pge_Next(&(pg->pge[PG_LEFT]));
|
||||||
|
pge_Next(&(pg->pge[PG_RIGHT]));
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pg_hline(pg, u8g2);
|
||||||
|
while ( pge_Next(&(pg->pge[PG_LEFT])) == 0 )
|
||||||
|
{
|
||||||
|
pg_line_init(pg, PG_LEFT);
|
||||||
|
}
|
||||||
|
while ( pge_Next(&(pg->pge[PG_RIGHT])) == 0 )
|
||||||
|
{
|
||||||
|
pg_line_init(pg, PG_RIGHT);
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
} while( i > 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================*/
|
||||||
|
/* API procedures */
|
||||||
|
|
||||||
|
static void pg_ClearPolygonXY(pg_struct *pg)
|
||||||
|
{
|
||||||
|
pg->cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pg_AddPolygonXY(pg_struct *pg, int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
if ( pg->cnt < PG_MAX_POINTS )
|
||||||
|
{
|
||||||
|
pg->list[pg->cnt].x = x;
|
||||||
|
pg->list[pg->cnt].y = y;
|
||||||
|
pg->cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pg_DrawPolygon(pg_struct *pg, u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
if ( pg_prepare(pg) == 0 )
|
||||||
|
return;
|
||||||
|
pg_exec(pg, u8g2);
|
||||||
|
}
|
||||||
|
|
||||||
|
pg_struct u8g2_pg;
|
||||||
|
|
||||||
|
void u8g2_ClearPolygonXY(void)
|
||||||
|
{
|
||||||
|
pg_ClearPolygonXY(&u8g2_pg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_AddPolygonXY(U8X8_UNUSED u8g2_t *u8g2, int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
pg_AddPolygonXY(&u8g2_pg, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawPolygon(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
pg_DrawPolygon(&u8g2_pg, u8g2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawTriangle(u8g2_t *u8g2, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
|
||||||
|
{
|
||||||
|
u8g2_ClearPolygonXY();
|
||||||
|
u8g2_AddPolygonXY(u8g2, x0, y0);
|
||||||
|
u8g2_AddPolygonXY(u8g2, x1, y1);
|
||||||
|
u8g2_AddPolygonXY(u8g2, x2, y2);
|
||||||
|
u8g2_DrawPolygon(u8g2);
|
||||||
|
}
|
||||||
|
|
||||||
289
main/utilities/u8g2/src/u8g2_selection_list.c
Normal file
289
main/utilities/u8g2/src/u8g2_selection_list.c
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_selection_list.c
|
||||||
|
|
||||||
|
selection list with scroll option
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
|
||||||
|
#define MY_BORDER_SIZE 1
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Draw a string at x,y
|
||||||
|
Center string within w (left adjust if w < pixel len of s)
|
||||||
|
|
||||||
|
Side effects:
|
||||||
|
u8g2_SetFontDirection(u8g2, 0);
|
||||||
|
u8g2_SetFontPosBaseline(u8g2);
|
||||||
|
|
||||||
|
*/
|
||||||
|
void u8g2_DrawUTF8Line(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, const char *s, uint8_t border_size, uint8_t is_invert)
|
||||||
|
{
|
||||||
|
u8g2_uint_t d, str_width;
|
||||||
|
u8g2_uint_t fx, fy, fw, fh;
|
||||||
|
|
||||||
|
/* only horizontal strings are supported, so force this here */
|
||||||
|
u8g2_SetFontDirection(u8g2, 0);
|
||||||
|
|
||||||
|
/* revert y position back to baseline ref */
|
||||||
|
y += u8g2->font_calc_vref(u8g2);
|
||||||
|
|
||||||
|
/* calculate the width of the string in pixel */
|
||||||
|
str_width = u8g2_GetUTF8Width(u8g2, s);
|
||||||
|
|
||||||
|
#ifdef U8G2_BALANCED_STR_WIDTH_CALCULATION
|
||||||
|
/* subtract the first character offset added by the width calculation */
|
||||||
|
str_width -= u8g2_GetXOffsetUTF8(u8g2, s);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* calculate delta d within the box */
|
||||||
|
d = 0;
|
||||||
|
if ( str_width < w )
|
||||||
|
{
|
||||||
|
d = w;
|
||||||
|
d -=str_width;
|
||||||
|
d /= 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
w = str_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* caluclate text box */
|
||||||
|
fx = x;
|
||||||
|
fy = y - u8g2_GetAscent(u8g2) ;
|
||||||
|
fw = w;
|
||||||
|
fh = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) ;
|
||||||
|
|
||||||
|
/* draw the box, if inverted */
|
||||||
|
u8g2_SetDrawColor(u8g2, 1);
|
||||||
|
if ( is_invert )
|
||||||
|
{
|
||||||
|
u8g2_DrawBox(u8g2, fx, fy, fw, fh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draw the frame */
|
||||||
|
while( border_size > 0 )
|
||||||
|
{
|
||||||
|
fx--;
|
||||||
|
fy--;
|
||||||
|
fw +=2;
|
||||||
|
fh +=2;
|
||||||
|
u8g2_DrawFrame(u8g2, fx, fy, fw, fh );
|
||||||
|
border_size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_invert )
|
||||||
|
{
|
||||||
|
u8g2_SetDrawColor(u8g2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8g2_SetDrawColor(u8g2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draw the text */
|
||||||
|
u8g2_DrawUTF8(u8g2, x+d, y, s);
|
||||||
|
|
||||||
|
/* revert draw color */
|
||||||
|
u8g2_SetDrawColor(u8g2, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
draw several lines at position x,y.
|
||||||
|
lines are stored in s and must be separated with '\n'.
|
||||||
|
lines can be centered with respect to "w"
|
||||||
|
if s == NULL nothing is drawn and 0 is returned
|
||||||
|
returns the number of lines in s multiplied with line_height
|
||||||
|
*/
|
||||||
|
u8g2_uint_t u8g2_DrawUTF8Lines(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t line_height, const char *s)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t cnt;
|
||||||
|
u8g2_uint_t yy = 0;
|
||||||
|
cnt = u8x8_GetStringLineCnt(s);
|
||||||
|
//printf("str=%s\n", s);
|
||||||
|
//printf("cnt=%d, y=%d, line_height=%d\n", cnt, y, line_height);
|
||||||
|
for( i = 0; i < cnt; i++ )
|
||||||
|
{
|
||||||
|
//printf(" i=%d, y=%d, line_height=%d\n", i, y, line_height);
|
||||||
|
u8g2_DrawUTF8Line(u8g2, x, y, w, u8x8_GetStringLineStart(i, s), 0, 0);
|
||||||
|
y+=line_height;
|
||||||
|
yy+=line_height;
|
||||||
|
}
|
||||||
|
return yy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
selection list with string line
|
||||||
|
returns line height
|
||||||
|
*/
|
||||||
|
static u8g2_uint_t u8g2_draw_selection_list_line(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, uint8_t idx, const char *s) U8G2_NOINLINE;
|
||||||
|
static u8g2_uint_t u8g2_draw_selection_list_line(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, uint8_t idx, const char *s)
|
||||||
|
{
|
||||||
|
//u8g2_uint_t yy;
|
||||||
|
uint8_t border_size = 0;
|
||||||
|
uint8_t is_invert = 0;
|
||||||
|
|
||||||
|
u8g2_uint_t line_height = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2)+MY_BORDER_SIZE;
|
||||||
|
|
||||||
|
/* calculate offset from display upper border */
|
||||||
|
//yy = idx;
|
||||||
|
//yy -= u8sl->first_pos;
|
||||||
|
//yy *= line_height;
|
||||||
|
//yy += y;
|
||||||
|
|
||||||
|
/* check whether this is the current cursor line */
|
||||||
|
if ( idx == u8sl->current_pos )
|
||||||
|
{
|
||||||
|
border_size = MY_BORDER_SIZE;
|
||||||
|
is_invert = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the line from the array */
|
||||||
|
s = u8x8_GetStringLineStart(idx, s);
|
||||||
|
|
||||||
|
/* draw the line */
|
||||||
|
if ( s == NULL )
|
||||||
|
s = "";
|
||||||
|
u8g2_DrawUTF8Line(u8g2, MY_BORDER_SIZE, y, u8g2_GetDisplayWidth(u8g2)-2*MY_BORDER_SIZE, s, border_size, is_invert);
|
||||||
|
return line_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_DrawSelectionList(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, const char *s)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
for( i = 0; i < u8sl->visible; i++ )
|
||||||
|
{
|
||||||
|
y += u8g2_draw_selection_list_line(u8g2, u8sl, y, i+u8sl->first_pos, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n'
|
||||||
|
start_pos: default position for the cursor, first line is 1.
|
||||||
|
sl: string list (list of strings separated by \n)
|
||||||
|
returns 0 if user has pressed the home key
|
||||||
|
returns the selected line if user has pressed the select key
|
||||||
|
side effects:
|
||||||
|
u8g2_SetFontDirection(u8g2, 0);
|
||||||
|
u8g2_SetFontPosBaseline(u8g2);
|
||||||
|
|
||||||
|
*/
|
||||||
|
uint8_t u8g2_UserInterfaceSelectionList(u8g2_t *u8g2, const char *title, uint8_t start_pos, const char *sl)
|
||||||
|
{
|
||||||
|
u8sl_t u8sl;
|
||||||
|
u8g2_uint_t yy;
|
||||||
|
|
||||||
|
uint8_t event;
|
||||||
|
|
||||||
|
u8g2_uint_t line_height = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2)+MY_BORDER_SIZE;
|
||||||
|
|
||||||
|
uint8_t title_lines = u8x8_GetStringLineCnt(title);
|
||||||
|
uint8_t display_lines;
|
||||||
|
|
||||||
|
|
||||||
|
if ( start_pos > 0 ) /* issue 112 */
|
||||||
|
start_pos--; /* issue 112 */
|
||||||
|
|
||||||
|
|
||||||
|
if ( title_lines > 0 )
|
||||||
|
{
|
||||||
|
display_lines = (u8g2_GetDisplayHeight(u8g2)-3) / line_height;
|
||||||
|
u8sl.visible = display_lines;
|
||||||
|
u8sl.visible -= title_lines;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
display_lines = u8g2_GetDisplayHeight(u8g2) / line_height;
|
||||||
|
u8sl.visible = display_lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8sl.total = u8x8_GetStringLineCnt(sl);
|
||||||
|
u8sl.first_pos = 0;
|
||||||
|
u8sl.current_pos = start_pos;
|
||||||
|
|
||||||
|
if ( u8sl.current_pos >= u8sl.total )
|
||||||
|
u8sl.current_pos = u8sl.total-1;
|
||||||
|
if ( u8sl.first_pos+u8sl.visible <= u8sl.current_pos )
|
||||||
|
u8sl.first_pos = u8sl.current_pos-u8sl.visible+1;
|
||||||
|
|
||||||
|
u8g2_SetFontPosBaseline(u8g2);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
u8g2_FirstPage(u8g2);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
yy = u8g2_GetAscent(u8g2);
|
||||||
|
if ( title_lines > 0 )
|
||||||
|
{
|
||||||
|
yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title);
|
||||||
|
|
||||||
|
u8g2_DrawHLine(u8g2, 0, yy-line_height- u8g2_GetDescent(u8g2) + 1, u8g2_GetDisplayWidth(u8g2));
|
||||||
|
|
||||||
|
yy += 3;
|
||||||
|
}
|
||||||
|
u8g2_DrawSelectionList(u8g2, &u8sl, yy, sl);
|
||||||
|
} while( u8g2_NextPage(u8g2) );
|
||||||
|
|
||||||
|
#ifdef U8G2_REF_MAN_PIC
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2));
|
||||||
|
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
|
||||||
|
return u8sl.current_pos+1; /* +1, issue 112 */
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
|
||||||
|
return 0; /* issue 112: return 0 instead of start_pos */
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN )
|
||||||
|
{
|
||||||
|
u8sl_Next(&u8sl);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP )
|
||||||
|
{
|
||||||
|
u8sl_Prev(&u8sl);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
469
main/utilities/u8g2/src/u8g2_setup.c
Normal file
469
main/utilities/u8g2/src/u8g2_setup.c
Normal file
@ -0,0 +1,469 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8g2_setup.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
|
||||||
|
|
||||||
|
void u8g2_SetMaxClipWindow(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2->clip_x0 = 0;
|
||||||
|
u8g2->clip_y0 = 0;
|
||||||
|
u8g2->clip_x1 = (u8g2_uint_t)~(u8g2_uint_t)0;
|
||||||
|
u8g2->clip_y1 = (u8g2_uint_t)~(u8g2_uint_t)0;
|
||||||
|
|
||||||
|
u8g2->cb->update_page_win(u8g2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_SetClipWindow(u8g2_t *u8g2, u8g2_uint_t clip_x0, u8g2_uint_t clip_y0, u8g2_uint_t clip_x1, u8g2_uint_t clip_y1 )
|
||||||
|
{
|
||||||
|
u8g2->clip_x0 = clip_x0;
|
||||||
|
u8g2->clip_y0 = clip_y0;
|
||||||
|
u8g2->clip_x1 = clip_x1;
|
||||||
|
u8g2->clip_y1 = clip_y1;
|
||||||
|
u8g2->cb->update_page_win(u8g2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
/*
|
||||||
|
This procedure is called after setting up the display (u8x8 structure).
|
||||||
|
--> This is the central init procedure for u8g2 object
|
||||||
|
*/
|
||||||
|
void u8g2_SetupBuffer(u8g2_t *u8g2, uint8_t *buf, uint8_t tile_buf_height, u8g2_draw_ll_hvline_cb ll_hvline_cb, const u8g2_cb_t *u8g2_cb)
|
||||||
|
{
|
||||||
|
u8g2->font = NULL;
|
||||||
|
//u8g2->kerning = NULL;
|
||||||
|
//u8g2->get_kerning_cb = u8g2_GetNullKerning;
|
||||||
|
|
||||||
|
//u8g2->ll_hvline = u8g2_ll_hvline_vertical_top_lsb;
|
||||||
|
u8g2->ll_hvline = ll_hvline_cb;
|
||||||
|
|
||||||
|
u8g2->tile_buf_ptr = buf;
|
||||||
|
u8g2->tile_buf_height = tile_buf_height;
|
||||||
|
|
||||||
|
u8g2->tile_curr_row = 0;
|
||||||
|
|
||||||
|
u8g2->font_decode.is_transparent = 0; /* issue 443 */
|
||||||
|
u8g2->bitmap_transparency = 0;
|
||||||
|
|
||||||
|
u8g2->font_height_mode = 0; /* issue 2046 */
|
||||||
|
u8g2->draw_color = 1;
|
||||||
|
u8g2->is_auto_page_clear = 1;
|
||||||
|
|
||||||
|
u8g2->cb = u8g2_cb;
|
||||||
|
u8g2->cb->update_dimension(u8g2);
|
||||||
|
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
|
||||||
|
u8g2_SetMaxClipWindow(u8g2); /* assign a clip window and call the update() procedure */
|
||||||
|
#else
|
||||||
|
u8g2->cb->update_page_win(u8g2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u8g2_SetFontPosBaseline(u8g2); /* issue 195 */
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_FONT_ROTATION
|
||||||
|
u8g2->font_decode.dir = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Usually the display rotation is set initially, but it could be done later also
|
||||||
|
u8g2_cb can be U8G2_R0..U8G2_R3
|
||||||
|
*/
|
||||||
|
void u8g2_SetDisplayRotation(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb)
|
||||||
|
{
|
||||||
|
u8g2->cb = u8g2_cb;
|
||||||
|
u8g2->cb->update_dimension(u8g2);
|
||||||
|
u8g2->cb->update_page_win(u8g2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
|
||||||
|
void u8g2_SendF(u8g2_t * u8g2, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
va_start(va, fmt);
|
||||||
|
u8x8_cad_vsendf(u8g2_GetU8x8(u8g2), fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
/*
|
||||||
|
update dimension:
|
||||||
|
calculate the following variables:
|
||||||
|
u8g2_uint_t buf_x0; left corner of the buffer
|
||||||
|
u8g2_uint_t buf_x1; right corner of the buffer (excluded)
|
||||||
|
u8g2_uint_t buf_y0;
|
||||||
|
u8g2_uint_t buf_y1;
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void u8g2_update_dimension_common(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
const u8x8_display_info_t *display_info = u8g2_GetU8x8(u8g2)->display_info;
|
||||||
|
u8g2_uint_t t;
|
||||||
|
|
||||||
|
t = u8g2->tile_buf_height;
|
||||||
|
t *= 8;
|
||||||
|
u8g2->pixel_buf_height = t;
|
||||||
|
|
||||||
|
t = display_info->tile_width;
|
||||||
|
#ifndef U8G2_16BIT
|
||||||
|
if ( t >= 32 )
|
||||||
|
t = 31;
|
||||||
|
#endif
|
||||||
|
t *= 8;
|
||||||
|
u8g2->pixel_buf_width = t;
|
||||||
|
|
||||||
|
t = u8g2->tile_curr_row;
|
||||||
|
t *= 8;
|
||||||
|
u8g2->pixel_curr_row = t;
|
||||||
|
|
||||||
|
t = u8g2->tile_buf_height;
|
||||||
|
/* handle the case, where the buffer is larger than the (remaining) part of the display */
|
||||||
|
if ( t + u8g2->tile_curr_row > display_info->tile_height )
|
||||||
|
t = display_info->tile_height - u8g2->tile_curr_row;
|
||||||
|
t *= 8;
|
||||||
|
|
||||||
|
u8g2->buf_y0 = u8g2->pixel_curr_row;
|
||||||
|
u8g2->buf_y1 = u8g2->buf_y0;
|
||||||
|
u8g2->buf_y1 += t;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef U8G2_16BIT
|
||||||
|
u8g2->width = display_info->pixel_width;
|
||||||
|
u8g2->height = display_info->pixel_height;
|
||||||
|
#else
|
||||||
|
u8g2->width = 240;
|
||||||
|
if ( display_info->pixel_width <= 240 )
|
||||||
|
u8g2->width = display_info->pixel_width;
|
||||||
|
u8g2->height = display_info->pixel_height;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==========================================================*/
|
||||||
|
/* apply clip window */
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
|
||||||
|
static void u8g2_apply_clip_window(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
/* check aganst the current user_??? window */
|
||||||
|
if ( u8g2_IsIntersection(u8g2, u8g2->clip_x0, u8g2->clip_y0, u8g2->clip_x1, u8g2->clip_y1) == 0 )
|
||||||
|
{
|
||||||
|
u8g2->is_page_clip_window_intersection = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8g2->is_page_clip_window_intersection = 1;
|
||||||
|
|
||||||
|
if ( u8g2->user_x0 < u8g2->clip_x0 )
|
||||||
|
u8g2->user_x0 = u8g2->clip_x0;
|
||||||
|
if ( u8g2->user_x1 > u8g2->clip_x1 )
|
||||||
|
u8g2->user_x1 = u8g2->clip_x1;
|
||||||
|
if ( u8g2->user_y0 < u8g2->clip_y0 )
|
||||||
|
u8g2->user_y0 = u8g2->clip_y0;
|
||||||
|
if ( u8g2->user_y1 > u8g2->clip_y1 )
|
||||||
|
u8g2->user_y1 = u8g2->clip_y1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
|
||||||
|
|
||||||
|
/*==========================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_update_dimension_r0(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2_update_dimension_common(u8g2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_update_page_win_r0(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2->user_x0 = 0;
|
||||||
|
u8g2->user_x1 = u8g2->width; /* pixel_buf_width replaced with width */
|
||||||
|
|
||||||
|
u8g2->user_y0 = u8g2->buf_y0;
|
||||||
|
u8g2->user_y1 = u8g2->buf_y1;
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
|
||||||
|
u8g2_apply_clip_window(u8g2);
|
||||||
|
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_update_dimension_r1(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2_update_dimension_common(u8g2);
|
||||||
|
|
||||||
|
u8g2->height = u8g2_GetU8x8(u8g2)->display_info->pixel_width;
|
||||||
|
u8g2->width = u8g2_GetU8x8(u8g2)->display_info->pixel_height;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_update_page_win_r1(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2->user_x0 = u8g2->buf_y0;
|
||||||
|
u8g2->user_x1 = u8g2->buf_y1;
|
||||||
|
|
||||||
|
u8g2->user_y0 = 0;
|
||||||
|
u8g2->user_y1 = u8g2->height; /* pixel_buf_width replaced with height (which is the real pixel width) */
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
|
||||||
|
u8g2_apply_clip_window(u8g2);
|
||||||
|
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_update_dimension_r2(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2_update_dimension_common(u8g2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_update_page_win_r2(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2->user_x0 = 0;
|
||||||
|
u8g2->user_x1 = u8g2->width; /* pixel_buf_width replaced with width */
|
||||||
|
|
||||||
|
/* there are ases where the height is not a multiple of 8. */
|
||||||
|
/* in such a case u8g2->buf_y1 might be heigher than u8g2->height */
|
||||||
|
u8g2->user_y0 = 0;
|
||||||
|
if ( u8g2->height >= u8g2->buf_y1 )
|
||||||
|
u8g2->user_y0 = u8g2->height - u8g2->buf_y1;
|
||||||
|
u8g2->user_y1 = u8g2->height - u8g2->buf_y0;
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
|
||||||
|
u8g2_apply_clip_window(u8g2);
|
||||||
|
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_update_dimension_r3(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
u8g2_update_dimension_common(u8g2);
|
||||||
|
|
||||||
|
u8g2->height = u8g2_GetU8x8(u8g2)->display_info->pixel_width;
|
||||||
|
u8g2->width = u8g2_GetU8x8(u8g2)->display_info->pixel_height;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_update_page_win_r3(u8g2_t *u8g2)
|
||||||
|
{
|
||||||
|
/* there are ases where the height is not a multiple of 8. */
|
||||||
|
/* in such a case u8g2->buf_y1 might be heigher than u8g2->width */
|
||||||
|
u8g2->user_x0 = 0;
|
||||||
|
if ( u8g2->width >= u8g2->buf_y1 )
|
||||||
|
u8g2->user_x0 = u8g2->width - u8g2->buf_y1;
|
||||||
|
u8g2->user_x1 = u8g2->width - u8g2->buf_y0;
|
||||||
|
|
||||||
|
u8g2->user_y0 = 0;
|
||||||
|
u8g2->user_y1 = u8g2->height; /* pixel_buf_width replaced with height (pixel_width) */
|
||||||
|
|
||||||
|
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
|
||||||
|
u8g2_apply_clip_window(u8g2);
|
||||||
|
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
extern void u8g2_draw_hv_line_2dir(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir);
|
||||||
|
|
||||||
|
|
||||||
|
void u8g2_draw_l90_r0(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
#ifdef __unix
|
||||||
|
assert( dir <= 1 );
|
||||||
|
#endif
|
||||||
|
u8g2_draw_hv_line_2dir(u8g2, x, y, len, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_draw_l90_mirrorr_r0(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
u8g2_uint_t xx;
|
||||||
|
xx = u8g2->width;
|
||||||
|
xx -= x;
|
||||||
|
if ( (dir & 1) == 0 )
|
||||||
|
{
|
||||||
|
xx -= len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xx--;
|
||||||
|
}
|
||||||
|
u8g2_draw_hv_line_2dir(u8g2, xx, y, len, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_draw_mirror_vertical_r0(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
u8g2_uint_t yy;
|
||||||
|
yy = u8g2->height;
|
||||||
|
yy -= y;
|
||||||
|
if ( (dir & 1) == 1 )
|
||||||
|
{
|
||||||
|
yy -= len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yy--;
|
||||||
|
}
|
||||||
|
u8g2_draw_hv_line_2dir(u8g2, x, yy, len, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dir = 0 or 1 */
|
||||||
|
void u8g2_draw_l90_r1(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
u8g2_uint_t xx, yy;
|
||||||
|
|
||||||
|
#ifdef __unix
|
||||||
|
assert( dir <= 1 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
yy = x;
|
||||||
|
|
||||||
|
xx = u8g2->height;
|
||||||
|
xx -= y;
|
||||||
|
xx--;
|
||||||
|
|
||||||
|
dir ++;
|
||||||
|
if ( dir == 2 )
|
||||||
|
{
|
||||||
|
xx -= len;
|
||||||
|
xx++;
|
||||||
|
dir = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8g2_draw_hv_line_2dir(u8g2, xx, yy, len, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_draw_l90_r2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
u8g2_uint_t xx, yy;
|
||||||
|
|
||||||
|
/*
|
||||||
|
yy = u8g2->height;
|
||||||
|
yy -= y;
|
||||||
|
yy--;
|
||||||
|
|
||||||
|
xx = u8g2->width;
|
||||||
|
xx -= x;
|
||||||
|
xx--;
|
||||||
|
|
||||||
|
if ( dir == 0 )
|
||||||
|
{
|
||||||
|
xx -= len;
|
||||||
|
xx++;
|
||||||
|
}
|
||||||
|
else if ( dir == 1 )
|
||||||
|
{
|
||||||
|
yy -= len;
|
||||||
|
yy++;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
yy = u8g2->height;
|
||||||
|
yy -= y;
|
||||||
|
|
||||||
|
xx = u8g2->width;
|
||||||
|
xx -= x;
|
||||||
|
|
||||||
|
if ( dir == 0 )
|
||||||
|
{
|
||||||
|
yy--;
|
||||||
|
xx -= len;
|
||||||
|
}
|
||||||
|
else if ( dir == 1 )
|
||||||
|
{
|
||||||
|
xx--;
|
||||||
|
yy -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8g2_draw_hv_line_2dir(u8g2, xx, yy, len, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8g2_draw_l90_r3(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
|
||||||
|
{
|
||||||
|
u8g2_uint_t xx, yy;
|
||||||
|
|
||||||
|
xx = y;
|
||||||
|
|
||||||
|
yy = u8g2->width;
|
||||||
|
yy -= x;
|
||||||
|
|
||||||
|
if ( dir == 0 )
|
||||||
|
{
|
||||||
|
yy--;
|
||||||
|
yy -= len;
|
||||||
|
yy++;
|
||||||
|
dir = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yy--;
|
||||||
|
dir = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u8g2_draw_hv_line_2dir(u8g2, xx, yy, len, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
const u8g2_cb_t u8g2_cb_r0 = { u8g2_update_dimension_r0, u8g2_update_page_win_r0, u8g2_draw_l90_r0 };
|
||||||
|
const u8g2_cb_t u8g2_cb_r1 = { u8g2_update_dimension_r1, u8g2_update_page_win_r1, u8g2_draw_l90_r1 };
|
||||||
|
const u8g2_cb_t u8g2_cb_r2 = { u8g2_update_dimension_r2, u8g2_update_page_win_r2, u8g2_draw_l90_r2 };
|
||||||
|
const u8g2_cb_t u8g2_cb_r3 = { u8g2_update_dimension_r3, u8g2_update_page_win_r3, u8g2_draw_l90_r3 };
|
||||||
|
|
||||||
|
const u8g2_cb_t u8g2_cb_mirror = { u8g2_update_dimension_r0, u8g2_update_page_win_r0, u8g2_draw_l90_mirrorr_r0 };
|
||||||
|
const u8g2_cb_t u8g2_cb_mirror_vertical = { u8g2_update_dimension_r0, u8g2_update_page_win_r0, u8g2_draw_mirror_vertical_r0 };
|
||||||
|
|
||||||
|
/*============================================*/
|
||||||
|
/* setup for the null device */
|
||||||
|
|
||||||
|
/* setup for the null (empty) device */
|
||||||
|
void u8g2_Setup_null(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
static uint8_t buf[8];
|
||||||
|
u8g2_SetupDisplay(u8g2, u8x8_d_null_cb, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
|
||||||
|
u8g2_SetupBuffer(u8g2, buf, 1, u8g2_ll_hvline_vertical_top_lsb, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
261
main/utilities/u8g2/src/u8log.c
Normal file
261
main/utilities/u8g2/src/u8log.c
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8log.c
|
||||||
|
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2018, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
static uint8_t u8log_is_on_screen(u8log_t *u8log, uint8_t x, uint8_t y)
|
||||||
|
{
|
||||||
|
if ( x >= u8log->width )
|
||||||
|
return 0;
|
||||||
|
if ( y >= u8log->height )
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void u8log_clear_screen(u8log_t *u8log)
|
||||||
|
{
|
||||||
|
uint8_t *dest = u8log->screen_buffer;
|
||||||
|
uint16_t cnt = u8log->height;
|
||||||
|
cnt *= u8log->width;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*dest++ = ' ';
|
||||||
|
cnt--;
|
||||||
|
} while( cnt > 0 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* scroll the content of the complete buffer, set redraw_line to 255 */
|
||||||
|
static void u8log_scroll_up(u8log_t *u8log)
|
||||||
|
{
|
||||||
|
uint8_t *dest = u8log->screen_buffer;
|
||||||
|
uint8_t *src = dest+u8log->width;
|
||||||
|
uint16_t cnt = u8log->height;
|
||||||
|
cnt--;
|
||||||
|
cnt *= u8log->width;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*dest++ = *src++;
|
||||||
|
cnt--;
|
||||||
|
} while( cnt > 0 );
|
||||||
|
cnt = u8log->width;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*dest++ = ' ';
|
||||||
|
cnt--;
|
||||||
|
} while(cnt > 0);
|
||||||
|
|
||||||
|
if ( u8log->is_redraw_line_for_each_char )
|
||||||
|
u8log->is_redraw_all = 1;
|
||||||
|
else
|
||||||
|
u8log->is_redraw_all_required_for_next_nl = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Place the cursor on the screen. This will also scroll, if required
|
||||||
|
*/
|
||||||
|
static void u8log_cursor_on_screen(u8log_t *u8log)
|
||||||
|
{
|
||||||
|
//printf("u8log_cursor_on_screen, cursor_y=%d\n", u8log->cursor_y);
|
||||||
|
if ( u8log->cursor_x >= u8log->width )
|
||||||
|
{
|
||||||
|
u8log->cursor_x = 0;
|
||||||
|
u8log->cursor_y++;
|
||||||
|
}
|
||||||
|
while ( u8log->cursor_y >= u8log->height )
|
||||||
|
{
|
||||||
|
u8log_scroll_up(u8log);
|
||||||
|
u8log->cursor_y--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Write a printable, single char on the screen, do any kind of scrolling
|
||||||
|
*/
|
||||||
|
static void u8log_write_to_screen(u8log_t *u8log, uint8_t c)
|
||||||
|
{
|
||||||
|
u8log_cursor_on_screen(u8log);
|
||||||
|
u8log->screen_buffer[u8log->cursor_y * u8log->width + u8log->cursor_x] = c;
|
||||||
|
u8log->cursor_x++;
|
||||||
|
|
||||||
|
if ( u8log->is_redraw_line_for_each_char )
|
||||||
|
{
|
||||||
|
u8log->is_redraw_line = 1;
|
||||||
|
u8log->redraw_line = u8log->cursor_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Handle control codes or write the char to the screen.
|
||||||
|
Supported control codes are:
|
||||||
|
|
||||||
|
\n 10 Goto first position of the next line. Line is marked for redraw.
|
||||||
|
\r 13 Goto first position in the same line. Line is marked for redraw.
|
||||||
|
\t 9 Jump to the next tab position
|
||||||
|
\f 12 Clear the screen and mark redraw for whole screen
|
||||||
|
any other char Write char to screen. Line redraw mark depends on
|
||||||
|
is_redraw_line_for_each_char flag.
|
||||||
|
*/
|
||||||
|
void u8log_write_char(u8log_t *u8log, uint8_t c)
|
||||||
|
{
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case '\n': // 10
|
||||||
|
u8log->is_redraw_line = 1;
|
||||||
|
u8log->redraw_line = u8log->cursor_y;
|
||||||
|
if ( u8log->is_redraw_all_required_for_next_nl )
|
||||||
|
u8log->is_redraw_all = 1;
|
||||||
|
u8log->is_redraw_all_required_for_next_nl = 0;
|
||||||
|
u8log->cursor_y++;
|
||||||
|
u8log->cursor_x = 0;
|
||||||
|
u8log_cursor_on_screen(u8log); // 31 Aug 2024 https://github.com/olikraus/u8g2/issues/2319
|
||||||
|
break;
|
||||||
|
case '\r': // 13
|
||||||
|
u8log->is_redraw_line = 1;
|
||||||
|
u8log->redraw_line = u8log->cursor_y;
|
||||||
|
u8log->cursor_x = 0;
|
||||||
|
break;
|
||||||
|
case '\t': // 9
|
||||||
|
u8log->cursor_x = (u8log->cursor_x + 8) & 0xf8;
|
||||||
|
break;
|
||||||
|
case '\f': // 12
|
||||||
|
u8log_clear_screen(u8log);
|
||||||
|
u8log->is_redraw_all = 1;
|
||||||
|
u8log->cursor_x = 0;
|
||||||
|
u8log->cursor_y = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
u8log_write_to_screen(u8log, c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8log_Init(u8log_t *u8log, uint8_t width, uint8_t height, uint8_t *buf)
|
||||||
|
{
|
||||||
|
memset(u8log, 0, sizeof(u8log_t));
|
||||||
|
u8log->width = width;
|
||||||
|
u8log->height = height;
|
||||||
|
u8log->screen_buffer = buf;
|
||||||
|
u8log_clear_screen(u8log);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8log_SetCallback(u8log_t *u8log, u8log_cb cb, void *aux_data)
|
||||||
|
{
|
||||||
|
u8log->cb = cb;
|
||||||
|
u8log->aux_data = aux_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8log_SetRedrawMode(u8log_t *u8log, uint8_t is_redraw_line_for_each_char)
|
||||||
|
{
|
||||||
|
u8log->is_redraw_line_for_each_char = is_redraw_line_for_each_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* offset can be negative or positive, it is 0 by default */
|
||||||
|
void u8log_SetLineHeightOffset(u8log_t *u8log, int8_t line_height_offset)
|
||||||
|
{
|
||||||
|
u8log->line_height_offset = line_height_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void u8log_WriteChar(u8log_t *u8log, uint8_t c)
|
||||||
|
{
|
||||||
|
u8log_write_char(u8log, c);
|
||||||
|
if ( u8log->is_redraw_line || u8log->is_redraw_all )
|
||||||
|
{
|
||||||
|
if ( u8log->cb != 0 )
|
||||||
|
{
|
||||||
|
u8log->cb(u8log);
|
||||||
|
}
|
||||||
|
u8log->is_redraw_line = 0;
|
||||||
|
u8log->is_redraw_all = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8log_WriteString(u8log_t *u8log, const char *s)
|
||||||
|
{
|
||||||
|
while( *s != '\0' )
|
||||||
|
{
|
||||||
|
u8log_WriteChar(u8log, *s);
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void u8log_WriteHexHalfByte(u8log_t *u8log, uint8_t b) U8X8_NOINLINE;
|
||||||
|
static void u8log_WriteHexHalfByte(u8log_t *u8log, uint8_t b)
|
||||||
|
{
|
||||||
|
b &= 0x0f;
|
||||||
|
if ( b < 10 )
|
||||||
|
u8log_WriteChar(u8log, b+'0');
|
||||||
|
else
|
||||||
|
u8log_WriteChar(u8log, b+'a'-10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8log_WriteHex8(u8log_t *u8log, uint8_t b)
|
||||||
|
{
|
||||||
|
u8log_WriteHexHalfByte(u8log, b >> 4);
|
||||||
|
u8log_WriteHexHalfByte(u8log, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8log_WriteHex16(u8log_t *u8log, uint16_t v)
|
||||||
|
{
|
||||||
|
u8log_WriteHex8(u8log, v>>8);
|
||||||
|
u8log_WriteHex8(u8log, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8log_WriteHex32(u8log_t *u8log, uint32_t v)
|
||||||
|
{
|
||||||
|
u8log_WriteHex16(u8log, v>>16);
|
||||||
|
u8log_WriteHex16(u8log, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* v = value, d = number of digits (1..3) */
|
||||||
|
void u8log_WriteDec8(u8log_t *u8log, uint8_t v, uint8_t d)
|
||||||
|
{
|
||||||
|
u8log_WriteString(u8log, u8x8_u8toa(v, d));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* v = value, d = number of digits (1..5) */
|
||||||
|
void u8log_WriteDec16(u8log_t *u8log, uint16_t v, uint8_t d)
|
||||||
|
{
|
||||||
|
u8log_WriteString(u8log, u8x8_u16toa(v, d));
|
||||||
|
}
|
||||||
98
main/utilities/u8g2/src/u8log_u8g2.c
Normal file
98
main/utilities/u8g2/src/u8log_u8g2.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8log_u8g2.c
|
||||||
|
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2018, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8g2.h"
|
||||||
|
/*
|
||||||
|
Draw the u8log text at the specified x/y position.
|
||||||
|
x/y position is the reference position of the first char of the first line.
|
||||||
|
the line height is
|
||||||
|
u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) + line_height_offset;
|
||||||
|
line_height_offset can be set with u8log_SetLineHeightOffset()
|
||||||
|
Use
|
||||||
|
u8g2_SetFontRefHeightText(u8g2_t *u8g2);
|
||||||
|
u8g2_SetFontRefHeightExtendedText(u8g2_t *u8g2);
|
||||||
|
u8g2_SetFontRefHeightAll(u8g2_t *u8g2);
|
||||||
|
to change the return values for u8g2_GetAscent and u8g2_GetDescent
|
||||||
|
|
||||||
|
*/
|
||||||
|
void u8g2_DrawLog(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8log_t *u8log)
|
||||||
|
{
|
||||||
|
u8g2_uint_t disp_x, disp_y;
|
||||||
|
uint8_t buf_x, buf_y;
|
||||||
|
uint8_t c;
|
||||||
|
|
||||||
|
disp_y = y;
|
||||||
|
u8g2_SetFontDirection(u8g2, 0);
|
||||||
|
for( buf_y = 0; buf_y < u8log->height; buf_y++ )
|
||||||
|
{
|
||||||
|
disp_x = x;
|
||||||
|
for( buf_x = 0; buf_x < u8log->width; buf_x++ )
|
||||||
|
{
|
||||||
|
c = u8log->screen_buffer[buf_y * u8log->width + buf_x];
|
||||||
|
disp_x += u8g2_DrawGlyph(u8g2, disp_x, disp_y, c);
|
||||||
|
}
|
||||||
|
disp_y += u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2);
|
||||||
|
disp_y += u8log->line_height_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
u8lib callback for u8g2
|
||||||
|
|
||||||
|
Only font direction 0 is supported: u8g2_SetFontDirection(u8g2, 0)
|
||||||
|
Use
|
||||||
|
u8g2_SetFontRefHeightText(u8g2_t *u8g2);
|
||||||
|
u8g2_SetFontRefHeightExtendedText(u8g2_t *u8g2);
|
||||||
|
u8g2_SetFontRefHeightAll(u8g2_t *u8g2);
|
||||||
|
to change the top offset and the line height and
|
||||||
|
u8log_SetLineHeightOffset(u8log_t *u8log, int8_t line_height_offset)
|
||||||
|
to change the line height.
|
||||||
|
|
||||||
|
*/
|
||||||
|
void u8log_u8g2_cb(u8log_t * u8log)
|
||||||
|
{
|
||||||
|
u8g2_t *u8g2 = (u8g2_t *)(u8log->aux_data);
|
||||||
|
if ( u8log->is_redraw_line || u8log->is_redraw_all )
|
||||||
|
{
|
||||||
|
u8g2_FirstPage(u8g2);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8g2_DrawLog( u8g2, 0, u8g2_GetAscent(u8g2), u8log);
|
||||||
|
}
|
||||||
|
while( u8g2_NextPage(u8g2) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
75
main/utilities/u8g2/src/u8log_u8x8.c
Normal file
75
main/utilities/u8g2/src/u8log_u8x8.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8log_u8x8.c
|
||||||
|
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2018, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
static void u8x8_DrawLogLine(u8x8_t *u8x8, uint8_t disp_x, uint8_t disp_y, uint8_t buf_y, u8log_t *u8log) U8X8_NOINLINE;
|
||||||
|
static void u8x8_DrawLogLine(u8x8_t *u8x8, uint8_t disp_x, uint8_t disp_y, uint8_t buf_y, u8log_t *u8log)
|
||||||
|
{
|
||||||
|
uint8_t buf_x;
|
||||||
|
uint8_t c;
|
||||||
|
for( buf_x = 0; buf_x < u8log->width; buf_x++ )
|
||||||
|
{
|
||||||
|
c = u8log->screen_buffer[buf_y * u8log->width + buf_x];
|
||||||
|
u8x8_DrawGlyph(u8x8, disp_x, disp_y, c);
|
||||||
|
disp_x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_DrawLog(u8x8_t *u8x8, uint8_t x, uint8_t y, u8log_t *u8log)
|
||||||
|
{
|
||||||
|
uint8_t buf_y;
|
||||||
|
for( buf_y = 0; buf_y < u8log->height; buf_y++ )
|
||||||
|
{
|
||||||
|
u8x8_DrawLogLine(u8x8, x, y, buf_y, u8log);
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void u8log_u8x8_cb(u8log_t * u8log)
|
||||||
|
{
|
||||||
|
u8x8_t *u8x8 = (u8x8_t *)(u8log->aux_data);
|
||||||
|
if ( u8log->is_redraw_all )
|
||||||
|
{
|
||||||
|
u8x8_DrawLog(u8x8, 0, 0, u8log);
|
||||||
|
}
|
||||||
|
else if ( u8log->is_redraw_line )
|
||||||
|
{
|
||||||
|
u8x8_DrawLogLine(u8x8, 0, u8log->redraw_line, u8log->redraw_line, u8log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
1327
main/utilities/u8g2/src/u8x8.h
Normal file
1327
main/utilities/u8g2/src/u8x8.h
Normal file
File diff suppressed because it is too large
Load Diff
493
main/utilities/u8g2/src/u8x8_8x8.c
Normal file
493
main/utilities/u8g2/src/u8x8_8x8.c
Normal file
@ -0,0 +1,493 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_8x8.c
|
||||||
|
|
||||||
|
font procedures, directly interfaces display procedures
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
#if defined(ESP8266)
|
||||||
|
uint8_t u8x8_pgm_read_esp(const uint8_t * addr)
|
||||||
|
{
|
||||||
|
uint32_t bytes;
|
||||||
|
bytes = *(uint32_t*)((uint32_t)addr & ~3);
|
||||||
|
return ((uint8_t*)&bytes)[(uint32_t)addr & 3];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void u8x8_SetFont(u8x8_t *u8x8, const uint8_t *font_8x8)
|
||||||
|
{
|
||||||
|
u8x8->font = font_8x8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Args:
|
||||||
|
u8x8: ptr to u8x8 structure
|
||||||
|
encoding: glyph for which the data is requested (must be between 0 and 255)
|
||||||
|
buf: pointer to 8 bytes
|
||||||
|
*/
|
||||||
|
void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset) U8X8_NOINLINE;
|
||||||
|
void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset)
|
||||||
|
{
|
||||||
|
uint8_t first, last, tiles, i;
|
||||||
|
uint16_t offset;
|
||||||
|
first = u8x8_pgm_read(u8x8->font+0);
|
||||||
|
last = u8x8_pgm_read(u8x8->font+1);
|
||||||
|
tiles = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
|
||||||
|
tiles *= u8x8_pgm_read(u8x8->font+3); /* new 2019 format */
|
||||||
|
|
||||||
|
/* get the glyph bitmap from the font */
|
||||||
|
if ( first <= encoding && encoding <= last )
|
||||||
|
{
|
||||||
|
offset = encoding;
|
||||||
|
offset -= first;
|
||||||
|
offset *= tiles; /* new 2019 format */
|
||||||
|
offset += tile_offset; /* new 2019 format */
|
||||||
|
offset *= 8;
|
||||||
|
offset +=4; /* changed from 2 to 4, new 2019 format */
|
||||||
|
for( i = 0; i < 8; i++ )
|
||||||
|
{
|
||||||
|
buf[i] = u8x8_pgm_read(u8x8->font+offset);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( i = 0; i < 8; i++ )
|
||||||
|
{
|
||||||
|
buf[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* invert the bitmap if required */
|
||||||
|
if ( u8x8->is_font_inverse_mode )
|
||||||
|
{
|
||||||
|
for( i = 0; i < 8; i++ )
|
||||||
|
{
|
||||||
|
buf[i] ^= 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_DrawGlyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding)
|
||||||
|
{
|
||||||
|
uint8_t th = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
|
||||||
|
uint8_t tv = u8x8_pgm_read(u8x8->font+3); /* new 2019 format */
|
||||||
|
uint8_t xx, tile;
|
||||||
|
uint8_t buf[8];
|
||||||
|
th += x;
|
||||||
|
tv += y;
|
||||||
|
tile = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
xx = x;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8x8_get_glyph_data(u8x8, encoding, buf, tile);
|
||||||
|
u8x8_DrawTile(u8x8, xx, y, 1, buf);
|
||||||
|
tile++;
|
||||||
|
xx++;
|
||||||
|
} while( xx < th );
|
||||||
|
y++;
|
||||||
|
} while( y < tv );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Source: http://graphics.stanford.edu/~seander/bithacks.html
|
||||||
|
Section: Interleave bits by Binary Magic Numbers
|
||||||
|
Original codes is here:
|
||||||
|
static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF};
|
||||||
|
static const unsigned int S[] = {1, 2, 4, 8};
|
||||||
|
|
||||||
|
unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x
|
||||||
|
unsigned int y; // are in the even positions and bits from y in the odd;
|
||||||
|
unsigned int z; // z gets the resulting 32-bit Morton Number.
|
||||||
|
// x and y must initially be less than 65536.
|
||||||
|
|
||||||
|
x = (x | (x << S[3])) & B[3];
|
||||||
|
x = (x | (x << S[2])) & B[2];
|
||||||
|
x = (x | (x << S[1])) & B[1];
|
||||||
|
x = (x | (x << S[0])) & B[0];
|
||||||
|
|
||||||
|
y = (y | (y << S[3])) & B[3];
|
||||||
|
y = (y | (y << S[2])) & B[2];
|
||||||
|
y = (y | (y << S[1])) & B[1];
|
||||||
|
y = (y | (y << S[0])) & B[0];
|
||||||
|
|
||||||
|
z = x | (y << 1);
|
||||||
|
*/
|
||||||
|
uint16_t u8x8_upscale_byte(uint8_t x)
|
||||||
|
{
|
||||||
|
uint16_t y = x;
|
||||||
|
y |= (y << 4); // x = (x | (x << S[2])) & B[2];
|
||||||
|
y &= 0x0f0f;
|
||||||
|
y |= (y << 2); // x = (x | (x << S[1])) & B[1];
|
||||||
|
y &= 0x3333;
|
||||||
|
y |= (y << 1); // x = (x | (x << S[0])) & B[0];
|
||||||
|
y &= 0x5555;
|
||||||
|
|
||||||
|
y |= (y << 1); // z = x | (y << 1);
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void u8x8_upscale_buf(uint8_t *src, uint8_t *dest) U8X8_NOINLINE;
|
||||||
|
static void u8x8_upscale_buf(uint8_t *src, uint8_t *dest)
|
||||||
|
{
|
||||||
|
uint8_t i = 4;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*dest++ = *src;
|
||||||
|
*dest++ = *src++;
|
||||||
|
i--;
|
||||||
|
} while( i > 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void u8x8_draw_2x2_subglyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding, uint8_t tile)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint16_t t;
|
||||||
|
uint8_t buf[8];
|
||||||
|
uint8_t buf1[8];
|
||||||
|
uint8_t buf2[8];
|
||||||
|
u8x8_get_glyph_data(u8x8, encoding, buf, tile);
|
||||||
|
for( i = 0; i < 8; i ++ )
|
||||||
|
{
|
||||||
|
t = u8x8_upscale_byte(buf[i]);
|
||||||
|
buf1[i] = t >> 8;
|
||||||
|
buf2[i] = t & 255;
|
||||||
|
}
|
||||||
|
u8x8_upscale_buf(buf2, buf);
|
||||||
|
u8x8_DrawTile(u8x8, x, y, 1, buf);
|
||||||
|
|
||||||
|
u8x8_upscale_buf(buf2+4, buf);
|
||||||
|
u8x8_DrawTile(u8x8, x+1, y, 1, buf);
|
||||||
|
|
||||||
|
u8x8_upscale_buf(buf1, buf);
|
||||||
|
u8x8_DrawTile(u8x8, x, y+1, 1, buf);
|
||||||
|
|
||||||
|
u8x8_upscale_buf(buf1+4, buf);
|
||||||
|
u8x8_DrawTile(u8x8, x+1, y+1, 1, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void u8x8_Draw2x2Glyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding)
|
||||||
|
{
|
||||||
|
uint8_t th = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
|
||||||
|
uint8_t tv = u8x8_pgm_read(u8x8->font+3); /* new 2019 format */
|
||||||
|
uint8_t xx, tile;
|
||||||
|
th *= 2;
|
||||||
|
th += x;
|
||||||
|
tv *= 2;
|
||||||
|
tv += y;
|
||||||
|
tile = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
xx = x;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8x8_draw_2x2_subglyph(u8x8, xx, y, encoding, tile);
|
||||||
|
tile++;
|
||||||
|
xx+=2;
|
||||||
|
} while( xx < th );
|
||||||
|
y+=2;
|
||||||
|
} while( y < tv );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* https://github.com/olikraus/u8g2/issues/474 */
|
||||||
|
static void u8x8_draw_1x2_subglyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding, uint8_t tile)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint16_t t;
|
||||||
|
uint8_t buf[8];
|
||||||
|
uint8_t buf1[8];
|
||||||
|
uint8_t buf2[8];
|
||||||
|
u8x8_get_glyph_data(u8x8, encoding, buf, tile);
|
||||||
|
for( i = 0; i < 8; i ++ )
|
||||||
|
{
|
||||||
|
t = u8x8_upscale_byte(buf[i]);
|
||||||
|
buf1[i] = t >> 8;
|
||||||
|
buf2[i] = t & 255;
|
||||||
|
}
|
||||||
|
u8x8_DrawTile(u8x8, x, y, 1, buf2);
|
||||||
|
u8x8_DrawTile(u8x8, x, y+1, 1, buf1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_Draw1x2Glyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding)
|
||||||
|
{
|
||||||
|
uint8_t th = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
|
||||||
|
uint8_t tv = u8x8_pgm_read(u8x8->font+3); /* new 2019 format */
|
||||||
|
uint8_t xx, tile;
|
||||||
|
th += x;
|
||||||
|
tv *= 2;
|
||||||
|
tv += y;
|
||||||
|
tile = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
xx = x;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8x8_draw_1x2_subglyph(u8x8, xx, y, encoding, tile);
|
||||||
|
tile++;
|
||||||
|
xx++;
|
||||||
|
} while( xx < th );
|
||||||
|
y+=2;
|
||||||
|
} while( y < tv );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
source: https://en.wikipedia.org/wiki/UTF-8
|
||||||
|
Bits from to bytes Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
|
||||||
|
7 U+0000 U+007F 1 0xxxxxxx
|
||||||
|
11 U+0080 U+07FF 2 110xxxxx 10xxxxxx
|
||||||
|
16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
|
||||||
|
21 U+10000 U+1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
|
26 U+200000 U+3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
|
31 U+4000000 U+7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* reset the internal state machine */
|
||||||
|
void u8x8_utf8_init(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
u8x8->utf8_state = 0; /* also reset during u8x8_SetupDefaults() */
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t u8x8_ascii_next(U8X8_UNUSED u8x8_t *u8x8, uint8_t b)
|
||||||
|
{
|
||||||
|
if ( b == 0 || b == '\n' ) /* '\n' terminates the string to support the string list procedures */
|
||||||
|
return 0x0ffff; /* end of string detected*/
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
pass a byte from an utf8 encoded string to the utf8 decoder state machine
|
||||||
|
returns
|
||||||
|
0x0fffe: no glyph, just continue
|
||||||
|
0x0ffff: end of string
|
||||||
|
anything else: The decoded encoding
|
||||||
|
*/
|
||||||
|
uint16_t u8x8_utf8_next(u8x8_t *u8x8, uint8_t b)
|
||||||
|
{
|
||||||
|
if ( b == 0 || b == '\n' ) /* '\n' terminates the string to support the string list procedures */
|
||||||
|
return 0x0ffff; /* end of string detected, pending UTF8 is discarded */
|
||||||
|
if ( u8x8->utf8_state == 0 )
|
||||||
|
{
|
||||||
|
if ( b >= 0xfc ) /* 6 byte sequence */
|
||||||
|
{
|
||||||
|
u8x8->utf8_state = 5;
|
||||||
|
b &= 1;
|
||||||
|
}
|
||||||
|
else if ( b >= 0xf8 )
|
||||||
|
{
|
||||||
|
u8x8->utf8_state = 4;
|
||||||
|
b &= 3;
|
||||||
|
}
|
||||||
|
else if ( b >= 0xf0 )
|
||||||
|
{
|
||||||
|
u8x8->utf8_state = 3;
|
||||||
|
b &= 7;
|
||||||
|
}
|
||||||
|
else if ( b >= 0xe0 )
|
||||||
|
{
|
||||||
|
u8x8->utf8_state = 2;
|
||||||
|
b &= 15;
|
||||||
|
}
|
||||||
|
else if ( b >= 0xc0 )
|
||||||
|
{
|
||||||
|
u8x8->utf8_state = 1;
|
||||||
|
b &= 0x01f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* do nothing, just use the value as encoding */
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
u8x8->encoding = b;
|
||||||
|
return 0x0fffe;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8x8->utf8_state--;
|
||||||
|
/* The case b < 0x080 (an illegal UTF8 encoding) is not checked here. */
|
||||||
|
u8x8->encoding<<=6;
|
||||||
|
b &= 0x03f;
|
||||||
|
u8x8->encoding |= b;
|
||||||
|
if ( u8x8->utf8_state != 0 )
|
||||||
|
return 0x0fffe; /* nothing to do yet */
|
||||||
|
}
|
||||||
|
return u8x8->encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE;
|
||||||
|
static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||||
|
{
|
||||||
|
uint16_t e;
|
||||||
|
uint8_t cnt = 0;
|
||||||
|
uint8_t th = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
|
||||||
|
|
||||||
|
u8x8_utf8_init(u8x8);
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
e = u8x8->next_cb(u8x8, (uint8_t)*s);
|
||||||
|
if ( e == 0x0ffff )
|
||||||
|
break;
|
||||||
|
s++;
|
||||||
|
if ( e != 0x0fffe )
|
||||||
|
{
|
||||||
|
u8x8_DrawGlyph(u8x8, x, y, e);
|
||||||
|
x+=th;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t u8x8_DrawString(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||||
|
{
|
||||||
|
u8x8->next_cb = u8x8_ascii_next;
|
||||||
|
return u8x8_draw_string(u8x8, x, y, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_DrawUTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||||
|
{
|
||||||
|
u8x8->next_cb = u8x8_utf8_next;
|
||||||
|
return u8x8_draw_string(u8x8, x, y, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t u8x8_draw_2x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE;
|
||||||
|
static uint8_t u8x8_draw_2x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||||
|
{
|
||||||
|
uint16_t e;
|
||||||
|
uint8_t cnt = 0;
|
||||||
|
uint8_t th = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
|
||||||
|
|
||||||
|
th <<= 1;
|
||||||
|
|
||||||
|
u8x8_utf8_init(u8x8);
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
e = u8x8->next_cb(u8x8, (uint8_t)*s);
|
||||||
|
if ( e == 0x0ffff )
|
||||||
|
break;
|
||||||
|
s++;
|
||||||
|
if ( e != 0x0fffe )
|
||||||
|
{
|
||||||
|
u8x8_Draw2x2Glyph(u8x8, x, y, e);
|
||||||
|
x+=th;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t u8x8_Draw2x2String(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||||
|
{
|
||||||
|
u8x8->next_cb = u8x8_ascii_next;
|
||||||
|
return u8x8_draw_2x2_string(u8x8, x, y, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_Draw2x2UTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||||
|
{
|
||||||
|
u8x8->next_cb = u8x8_utf8_next;
|
||||||
|
return u8x8_draw_2x2_string(u8x8, x, y, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t u8x8_draw_1x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE;
|
||||||
|
static uint8_t u8x8_draw_1x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||||
|
{
|
||||||
|
uint16_t e;
|
||||||
|
uint8_t cnt = 0;
|
||||||
|
uint8_t th = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
|
||||||
|
u8x8_utf8_init(u8x8);
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
e = u8x8->next_cb(u8x8, (uint8_t)*s);
|
||||||
|
if ( e == 0x0ffff )
|
||||||
|
break;
|
||||||
|
s++;
|
||||||
|
if ( e != 0x0fffe )
|
||||||
|
{
|
||||||
|
u8x8_Draw1x2Glyph(u8x8, x, y, e);
|
||||||
|
x+=th;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t u8x8_Draw1x2String(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||||
|
{
|
||||||
|
u8x8->next_cb = u8x8_ascii_next;
|
||||||
|
return u8x8_draw_1x2_string(u8x8, x, y, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_Draw1x2UTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||||
|
{
|
||||||
|
u8x8->next_cb = u8x8_utf8_next;
|
||||||
|
return u8x8_draw_1x2_string(u8x8, x, y, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t u8x8_GetUTF8Len(u8x8_t *u8x8, const char *s)
|
||||||
|
{
|
||||||
|
uint16_t e;
|
||||||
|
uint8_t cnt = 0;
|
||||||
|
u8x8_utf8_init(u8x8);
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
e = u8x8_utf8_next(u8x8, *s);
|
||||||
|
if ( e == 0x0ffff )
|
||||||
|
break;
|
||||||
|
s++;
|
||||||
|
if ( e != 0x0fffe )
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
667
main/utilities/u8g2/src/u8x8_byte.c
Normal file
667
main/utilities/u8g2/src/u8x8_byte.c
Normal file
@ -0,0 +1,667 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_byte.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_SetDC(u8x8_t *u8x8, uint8_t dc)
|
||||||
|
{
|
||||||
|
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_SET_DC, dc, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_SendBytes(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
|
||||||
|
{
|
||||||
|
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_SEND, cnt, (void *)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_SendByte(u8x8_t *u8x8, uint8_t byte)
|
||||||
|
{
|
||||||
|
return u8x8_byte_SendBytes(u8x8, 1, &byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_StartTransfer(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_START_TRANSFER, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_EndTransfer(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_END_TRANSFER, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================*/
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_empty(U8X8_UNUSED u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
|
||||||
|
{
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_BYTE_SEND:
|
||||||
|
case U8X8_MSG_BYTE_INIT:
|
||||||
|
case U8X8_MSG_BYTE_SET_DC:
|
||||||
|
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||||
|
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||||
|
break; /* do nothing */
|
||||||
|
}
|
||||||
|
return 1; /* always succeed */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*=========================================*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Uses:
|
||||||
|
u8x8->display_info->sda_setup_time_ns
|
||||||
|
u8x8->display_info->sck_pulse_width_ns
|
||||||
|
u8x8->display_info->spi_mode
|
||||||
|
u8x8->display_info->chip_disable_level
|
||||||
|
u8x8->display_info->chip_enable_level
|
||||||
|
u8x8->display_info->post_chip_enable_wait_ns
|
||||||
|
u8x8->display_info->pre_chip_disable_wait_ns
|
||||||
|
Calls to GPIO and DELAY:
|
||||||
|
U8X8_MSG_DELAY_NANO
|
||||||
|
U8X8_MSG_GPIO_DC
|
||||||
|
U8X8_MSG_GPIO_CS
|
||||||
|
U8X8_MSG_GPIO_CLOCK
|
||||||
|
U8X8_MSG_GPIO_DATA
|
||||||
|
Handles:
|
||||||
|
U8X8_MSG_BYTE_INIT
|
||||||
|
U8X8_MSG_BYTE_SEND
|
||||||
|
U8X8_MSG_BYTE_SET_DC
|
||||||
|
U8X8_MSG_BYTE_START_TRANSFER
|
||||||
|
U8X8_MSG_BYTE_END_TRANSFER
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t i, b;
|
||||||
|
uint8_t *data;
|
||||||
|
uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
|
||||||
|
uint8_t not_takeover_edge = 1 - takeover_edge;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_BYTE_SEND:
|
||||||
|
data = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 0 )
|
||||||
|
{
|
||||||
|
b = *data;
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
for( i = 0; i < 8; i++ )
|
||||||
|
{
|
||||||
|
if ( b & 128 )
|
||||||
|
u8x8_gpio_SetSPIData(u8x8, 1);
|
||||||
|
else
|
||||||
|
u8x8_gpio_SetSPIData(u8x8, 0);
|
||||||
|
b <<= 1;
|
||||||
|
|
||||||
|
u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
|
||||||
|
u8x8_gpio_SetSPIClock(u8x8, takeover_edge);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case U8X8_MSG_BYTE_INIT:
|
||||||
|
/* disable chipselect */
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||||
|
/* no wait required here */
|
||||||
|
|
||||||
|
/* for SPI: setup correct level of the clock signal */
|
||||||
|
u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_SET_DC:
|
||||||
|
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================*/
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_8bit_6800mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t i, b;
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_BYTE_SEND:
|
||||||
|
data = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 0 )
|
||||||
|
{
|
||||||
|
b = *data;
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
|
||||||
|
{
|
||||||
|
u8x8_gpio_call(u8x8, i, b&1);
|
||||||
|
b >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case U8X8_MSG_BYTE_INIT:
|
||||||
|
/* disable chipselect */
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||||
|
/* ensure that the enable signal is high */
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_SET_DC:
|
||||||
|
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t i, b;
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_BYTE_SEND:
|
||||||
|
data = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 0 )
|
||||||
|
{
|
||||||
|
b = *data;
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
|
||||||
|
{
|
||||||
|
u8x8_gpio_call(u8x8, i, b&1);
|
||||||
|
b >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case U8X8_MSG_BYTE_INIT:
|
||||||
|
/* disable chipselect */
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||||
|
/* ensure that the enable signal is high */
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_SET_DC:
|
||||||
|
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================*/
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t *data;
|
||||||
|
uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
|
||||||
|
uint8_t not_takeover_edge = 1 - takeover_edge;
|
||||||
|
uint16_t b;
|
||||||
|
static uint8_t last_dc;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_BYTE_SEND:
|
||||||
|
data = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 0 )
|
||||||
|
{
|
||||||
|
b = *data;
|
||||||
|
if ( last_dc != 0 )
|
||||||
|
b |= 256;
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
for( i = 0; i < 9; i++ )
|
||||||
|
{
|
||||||
|
if ( b & 256 )
|
||||||
|
u8x8_gpio_SetSPIData(u8x8, 1);
|
||||||
|
else
|
||||||
|
u8x8_gpio_SetSPIData(u8x8, 0);
|
||||||
|
b <<= 1;
|
||||||
|
|
||||||
|
u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
|
||||||
|
u8x8_gpio_SetSPIClock(u8x8, takeover_edge);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case U8X8_MSG_BYTE_INIT:
|
||||||
|
/* disable chipselect */
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||||
|
/* no wait required here */
|
||||||
|
|
||||||
|
/* for SPI: setup correct level of the clock signal */
|
||||||
|
u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_SET_DC:
|
||||||
|
last_dc = arg_int;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================*/
|
||||||
|
|
||||||
|
void u8x8_byte_set_ks0108_cs(u8x8_t *u8x8, uint8_t arg)
|
||||||
|
{
|
||||||
|
u8x8_gpio_SetCS(u8x8, arg&1);
|
||||||
|
arg = arg >> 1;
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS1, arg&1);
|
||||||
|
arg = arg >> 1;
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS2, arg&1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 6800 mode */
|
||||||
|
uint8_t u8x8_byte_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t i, b;
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_BYTE_SEND:
|
||||||
|
data = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 0 )
|
||||||
|
{
|
||||||
|
b = *data;
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
|
||||||
|
{
|
||||||
|
u8x8_gpio_call(u8x8, i, b&1);
|
||||||
|
b >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case U8X8_MSG_BYTE_INIT:
|
||||||
|
/* disable chipselect */
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||||
|
/* ensure that the enable signal is low */
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_SET_DC:
|
||||||
|
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||||
|
/* expects 3 bits in arg_int for the chip select lines */
|
||||||
|
u8x8_byte_set_ks0108_cs(u8x8, arg_int);
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
|
||||||
|
u8x8_byte_set_ks0108_cs(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* sed1520 or sbn1661
|
||||||
|
U8X8_MSG_GPIO_E --> E1
|
||||||
|
U8X8_MSG_GPIO_CS --> E2
|
||||||
|
*/
|
||||||
|
uint8_t u8x8_byte_sed1520(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t i, b;
|
||||||
|
uint8_t *data;
|
||||||
|
static uint8_t enable_pin;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_BYTE_SEND:
|
||||||
|
data = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 0 )
|
||||||
|
{
|
||||||
|
b = *data;
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
|
||||||
|
{
|
||||||
|
u8x8_gpio_call(u8x8, i, b&1);
|
||||||
|
b >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
|
||||||
|
u8x8_gpio_call(u8x8, enable_pin, 1);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 200); /* KS0108 requires 450 ns, use 200 here */
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns); /* expect 250 here */
|
||||||
|
u8x8_gpio_call(u8x8, enable_pin, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case U8X8_MSG_BYTE_INIT:
|
||||||
|
/* disable chipselect */
|
||||||
|
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||||
|
/* ensure that the enable signals are low */
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS, 0);
|
||||||
|
enable_pin = U8X8_MSG_GPIO_E;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_SET_DC:
|
||||||
|
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||||
|
/* cs lines are not supported for the SED1520/SBN1661 */
|
||||||
|
/* instead, this will select the E1 or E2 line */
|
||||||
|
/* arg_int is set by u8x8_d_sbn1661_122x32() function */
|
||||||
|
enable_pin = U8X8_MSG_GPIO_E;
|
||||||
|
if ( arg_int != 0 )
|
||||||
|
enable_pin = U8X8_MSG_GPIO_CS;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
software i2c,
|
||||||
|
ignores ACK response (which is anyway not provided by some displays)
|
||||||
|
also does not allow reading from the device
|
||||||
|
*/
|
||||||
|
static void i2c_delay(u8x8_t *u8x8) U8X8_NOINLINE;
|
||||||
|
static void i2c_delay(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
//u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_10MICRO, u8x8->display_info->i2c_bus_clock_100kHz);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_I2C, u8x8->display_info->i2c_bus_clock_100kHz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_init(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
u8x8_gpio_SetI2CClock(u8x8, 1);
|
||||||
|
u8x8_gpio_SetI2CData(u8x8, 1);
|
||||||
|
|
||||||
|
i2c_delay(u8x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* actually, the scl line is not observed, so this procedure does not return a value */
|
||||||
|
|
||||||
|
static void i2c_read_scl_and_delay(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
/* set as input (line will be high) */
|
||||||
|
u8x8_gpio_SetI2CClock(u8x8, 1);
|
||||||
|
|
||||||
|
i2c_delay(u8x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_clear_scl(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
u8x8_gpio_SetI2CClock(u8x8, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_read_sda(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
/* set as input (line will be high) */
|
||||||
|
u8x8_gpio_SetI2CData(u8x8, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_clear_sda(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
/* set open collector and drive low */
|
||||||
|
u8x8_gpio_SetI2CData(u8x8, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_start(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
if ( u8x8->i2c_started != 0 )
|
||||||
|
{
|
||||||
|
/* if already started: do restart */
|
||||||
|
i2c_read_sda(u8x8); /* SDA = 1 */
|
||||||
|
i2c_delay(u8x8);
|
||||||
|
i2c_read_scl_and_delay(u8x8);
|
||||||
|
}
|
||||||
|
i2c_read_sda(u8x8);
|
||||||
|
/* send the start condition, both lines go from 1 to 0 */
|
||||||
|
i2c_clear_sda(u8x8);
|
||||||
|
i2c_delay(u8x8);
|
||||||
|
i2c_clear_scl(u8x8);
|
||||||
|
u8x8->i2c_started = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void i2c_stop(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
/* set SDA to 0 */
|
||||||
|
i2c_clear_sda(u8x8);
|
||||||
|
i2c_delay(u8x8);
|
||||||
|
|
||||||
|
/* now release all lines */
|
||||||
|
i2c_read_scl_and_delay(u8x8);
|
||||||
|
|
||||||
|
/* set SDA to 1 */
|
||||||
|
i2c_read_sda(u8x8);
|
||||||
|
i2c_delay(u8x8);
|
||||||
|
u8x8->i2c_started = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_write_bit(u8x8_t *u8x8, uint8_t val)
|
||||||
|
{
|
||||||
|
if (val)
|
||||||
|
i2c_read_sda(u8x8);
|
||||||
|
else
|
||||||
|
i2c_clear_sda(u8x8);
|
||||||
|
|
||||||
|
i2c_delay(u8x8);
|
||||||
|
i2c_read_scl_and_delay(u8x8);
|
||||||
|
i2c_clear_scl(u8x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_read_bit(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
//uint8_t val;
|
||||||
|
/* do not drive SDA */
|
||||||
|
i2c_read_sda(u8x8);
|
||||||
|
i2c_delay(u8x8);
|
||||||
|
i2c_read_scl_and_delay(u8x8);
|
||||||
|
i2c_read_sda(u8x8);
|
||||||
|
i2c_delay(u8x8);
|
||||||
|
i2c_clear_scl(u8x8);
|
||||||
|
//return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_write_byte(u8x8_t *u8x8, uint8_t b)
|
||||||
|
{
|
||||||
|
i2c_write_bit(u8x8, b & 128);
|
||||||
|
i2c_write_bit(u8x8, b & 64);
|
||||||
|
i2c_write_bit(u8x8, b & 32);
|
||||||
|
i2c_write_bit(u8x8, b & 16);
|
||||||
|
i2c_write_bit(u8x8, b & 8);
|
||||||
|
i2c_write_bit(u8x8, b & 4);
|
||||||
|
i2c_write_bit(u8x8, b & 2);
|
||||||
|
i2c_write_bit(u8x8, b & 1);
|
||||||
|
|
||||||
|
/* read ack from client */
|
||||||
|
/* 0: ack was given by client */
|
||||||
|
/* 1: nothing happend during ack cycle */
|
||||||
|
i2c_read_bit(u8x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_BYTE_SEND:
|
||||||
|
data = (uint8_t *)arg_ptr;
|
||||||
|
|
||||||
|
while( arg_int > 0 )
|
||||||
|
{
|
||||||
|
i2c_write_byte(u8x8, *data);
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case U8X8_MSG_BYTE_INIT:
|
||||||
|
i2c_init(u8x8);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_SET_DC:
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||||
|
i2c_start(u8x8);
|
||||||
|
i2c_write_byte(u8x8, u8x8_GetI2CAddress(u8x8));
|
||||||
|
//i2c_write_byte(u8x8, 0x078);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||||
|
i2c_stop(u8x8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================*/
|
||||||
|
|
||||||
|
/* alternative i2c byte procedure */
|
||||||
|
#ifdef ALTERNATIVE_I2C_BYTE_PROCEDURE
|
||||||
|
|
||||||
|
|
||||||
|
void i2c_transfer(u8x8_t *u8x8, uint8_t adr, uint8_t cnt, uint8_t *data)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
i2c_start(u8x8);
|
||||||
|
i2c_write_byte(u8x8, adr);
|
||||||
|
for( i = 0; i < cnt; i++ )
|
||||||
|
i2c_write_byte(u8x8, data[i]);
|
||||||
|
i2c_stop(u8x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t u8x8_byte_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
static uint8_t buffer[32]; /* u8g2/u8x8 will never send more than 32 bytes */
|
||||||
|
static uint8_t buf_idx;
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_BYTE_SEND:
|
||||||
|
data = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 0 )
|
||||||
|
{
|
||||||
|
buffer[buf_idx++] = *data;
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_INIT:
|
||||||
|
i2c_init(u8x8); /* init i2c communication */
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_SET_DC:
|
||||||
|
/* ignored for i2c */
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||||
|
buf_idx = 0;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||||
|
i2c_transfer(u8x8, u8x8_GetI2CAddress(u8x8), buf_idx, buffer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
951
main/utilities/u8g2/src/u8x8_cad.c
Normal file
951
main/utilities/u8g2/src/u8x8_cad.c
Normal file
@ -0,0 +1,951 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_cad.c
|
||||||
|
|
||||||
|
"command arg data" interface to the graphics controller
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
The following sequence must be used for any data, which is set to the display:
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8)
|
||||||
|
|
||||||
|
any of the following calls
|
||||||
|
uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd)
|
||||||
|
uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg)
|
||||||
|
uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
|
||||||
|
|
||||||
|
uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
uint8_t u8x8_cad_template(u8x8_t *u8x8, uint8_t msg, uint16_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
u8x8_mcd_byte_SetDC(mcd->next, 1);
|
||||||
|
u8x8_mcd_byte_Send(mcd->next, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_mcd_byte_SetDC(mcd->next, 1);
|
||||||
|
u8x8_mcd_byte_Send(mcd->next, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
u8x8_mcd_byte_SetDC(mcd->next, 0);
|
||||||
|
for( i = 0; i < 8; i++ )
|
||||||
|
u8x8_mcd_byte_Send(mcd->next, ((uint8_t *)arg_ptr)[i]);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_RESET:
|
||||||
|
return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd)
|
||||||
|
{
|
||||||
|
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_CMD, cmd, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg)
|
||||||
|
{
|
||||||
|
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_ARG, arg, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_cad_SendMultipleArg(u8x8_t *u8x8, uint8_t cnt, uint8_t arg)
|
||||||
|
{
|
||||||
|
while( cnt > 0 )
|
||||||
|
{
|
||||||
|
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_ARG, arg, NULL);
|
||||||
|
cnt--;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
|
||||||
|
{
|
||||||
|
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, cnt, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_cad_vsendf(u8x8_t * u8x8, const char *fmt, va_list va)
|
||||||
|
{
|
||||||
|
uint8_t d;
|
||||||
|
u8x8_cad_StartTransfer(u8x8);
|
||||||
|
while( *fmt != '\0' )
|
||||||
|
{
|
||||||
|
d = (uint8_t)va_arg(va, int);
|
||||||
|
switch(*fmt)
|
||||||
|
{
|
||||||
|
case 'a': u8x8_cad_SendArg(u8x8, d); break;
|
||||||
|
case 'c': u8x8_cad_SendCmd(u8x8, d); break;
|
||||||
|
case 'd': u8x8_cad_SendData(u8x8, 1, &d); break;
|
||||||
|
}
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
u8x8_cad_EndTransfer(u8x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_SendF(u8x8_t * u8x8, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
va_start(va, fmt);
|
||||||
|
u8x8_cad_vsendf(u8x8, fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
21 c send command c
|
||||||
|
22 a send arg a
|
||||||
|
23 d send data d
|
||||||
|
24 CS on
|
||||||
|
25 CS off
|
||||||
|
254 milli delay by milliseconds
|
||||||
|
255 end of sequence
|
||||||
|
*/
|
||||||
|
|
||||||
|
void u8x8_cad_SendSequence(u8x8_t *u8x8, uint8_t const *data)
|
||||||
|
{
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t v;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
cmd = *data;
|
||||||
|
data++;
|
||||||
|
switch( cmd )
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
v = *data;
|
||||||
|
u8x8->cad_cb(u8x8, cmd, v, NULL);
|
||||||
|
data++;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
v = *data;
|
||||||
|
u8x8_cad_SendData(u8x8, 1, &v);
|
||||||
|
data++;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
u8x8->cad_cb(u8x8, cmd, 0, NULL);
|
||||||
|
break;
|
||||||
|
case 0x0fe:
|
||||||
|
v = *data;
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, v);
|
||||||
|
data++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t u8x8_cad_empty(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
convert to bytes by using
|
||||||
|
dc = 1 for commands and args and
|
||||||
|
dc = 0 for data
|
||||||
|
*/
|
||||||
|
uint8_t u8x8_cad_110(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
u8x8_byte_SetDC(u8x8, 1);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_SetDC(u8x8, 1);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
u8x8_byte_SetDC(u8x8, 0);
|
||||||
|
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
|
||||||
|
//break;
|
||||||
|
/* fall through */
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
convert to bytes by using
|
||||||
|
dc = 1 for commands and args and
|
||||||
|
dc = 0 for data
|
||||||
|
*/
|
||||||
|
uint8_t u8x8_gu800_cad_110(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t *data;
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
u8x8_byte_SetDC(u8x8, 1);
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_SetDC(u8x8, 1);
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
u8x8_byte_SetDC(u8x8, 0);
|
||||||
|
data = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 0 )
|
||||||
|
{
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, *data);
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
convert to bytes by using
|
||||||
|
dc = 1 for commands and args and
|
||||||
|
dc = 0 for data
|
||||||
|
t6963
|
||||||
|
*/
|
||||||
|
uint8_t u8x8_cad_100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
u8x8_byte_SetDC(u8x8, 1);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_SetDC(u8x8, 0);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
u8x8_byte_SetDC(u8x8, 0);
|
||||||
|
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
|
||||||
|
//break;
|
||||||
|
/* fall through */
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
convert to bytes by using
|
||||||
|
dc = 0 for commands and args and
|
||||||
|
dc = 1 for data
|
||||||
|
*/
|
||||||
|
uint8_t u8x8_cad_001(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
u8x8_byte_SetDC(u8x8, 0);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_SetDC(u8x8, 0);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
u8x8_byte_SetDC(u8x8, 1);
|
||||||
|
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
|
||||||
|
//break;
|
||||||
|
/* fall through */
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
convert to bytes by using
|
||||||
|
dc = 0 for commands
|
||||||
|
dc = 1 for args and data
|
||||||
|
*/
|
||||||
|
uint8_t u8x8_cad_011(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
u8x8_byte_SetDC(u8x8, 0);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_SetDC(u8x8, 1);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
u8x8_byte_SetDC(u8x8, 1);
|
||||||
|
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
|
||||||
|
//break;
|
||||||
|
/* fall through */
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cad procedure for the ST7920 in SPI mode */
|
||||||
|
/* u8x8_byte_SetDC is not used */
|
||||||
|
uint8_t u8x8_cad_st7920_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t *data;
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t i;
|
||||||
|
static uint8_t buf[16];
|
||||||
|
uint8_t *ptr;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x0f8);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int & 0x0f0);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int << 4);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x0f8);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int & 0x0f0);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int << 4);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x0fa);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
|
||||||
|
|
||||||
|
/* this loop should be optimized: multiple bytes should be sent */
|
||||||
|
/* u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr); */
|
||||||
|
data = (uint8_t *)arg_ptr;
|
||||||
|
|
||||||
|
/* the following loop increases speed by 20% */
|
||||||
|
while( arg_int >= 8 )
|
||||||
|
{
|
||||||
|
i = 8;
|
||||||
|
ptr = buf;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
b = *data++;
|
||||||
|
*ptr++= b & 0x0f0;
|
||||||
|
b <<= 4;
|
||||||
|
*ptr++= b;
|
||||||
|
i--;
|
||||||
|
} while( i > 0 );
|
||||||
|
arg_int -= 8;
|
||||||
|
u8x8_byte_SendBytes(u8x8, 16, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while( arg_int > 0 )
|
||||||
|
{
|
||||||
|
b = *data;
|
||||||
|
u8x8_byte_SendByte(u8x8, b & 0x0f0);
|
||||||
|
u8x8_byte_SendByte(u8x8, b << 4);
|
||||||
|
data++;
|
||||||
|
arg_int--;
|
||||||
|
}
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cad procedure for the SSD13xx family in I2C mode */
|
||||||
|
/* this procedure is also used by the ST7588 */
|
||||||
|
/* u8x8_byte_SetDC is not used */
|
||||||
|
/* U8X8_MSG_BYTE_START_TRANSFER starts i2c transfer, U8X8_MSG_BYTE_END_TRANSFER stops transfer */
|
||||||
|
/* After transfer start, a full byte indicates command or data mode */
|
||||||
|
|
||||||
|
static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE;
|
||||||
|
static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x040);
|
||||||
|
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, arg_ptr);
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* classic version: will put a start/stop condition around each command and arg */
|
||||||
|
/* implements CAD = 001 */
|
||||||
|
uint8_t u8x8_cad_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t *p;
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
/* 7 Nov 2016: Can this be improved? */
|
||||||
|
//u8x8_byte_SetDC(u8x8, 0);
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
//u8x8_byte_SendByte(u8x8, u8x8_GetI2CAddress(u8x8));
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x000);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
//u8x8_byte_SetDC(u8x8, 1);
|
||||||
|
|
||||||
|
/* the FeatherWing OLED with the 32u4 transfer of long byte */
|
||||||
|
/* streams was not possible. This is broken down to */
|
||||||
|
/* smaller streams, 32 seems to be the limit... */
|
||||||
|
/* I guess this is related to the size of the Wire buffers in Arduino */
|
||||||
|
/* Unfortunately, this can not be handled in the byte level drivers, */
|
||||||
|
/* so this is done here. Even further, only 24 bytes will be sent, */
|
||||||
|
/* because there will be another byte (DC) required during the transfer */
|
||||||
|
p = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 24 )
|
||||||
|
{
|
||||||
|
u8x8_i2c_data_transfer(u8x8, 24, p);
|
||||||
|
arg_int-=24;
|
||||||
|
p+=24;
|
||||||
|
}
|
||||||
|
u8x8_i2c_data_transfer(u8x8, arg_int, p);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||||
|
if ( u8x8->i2c_address == 255 )
|
||||||
|
u8x8->i2c_address = 0x078;
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
/* cad transfer commands are ignored */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* classic version: will put a start/stop condition around each command and arg */
|
||||||
|
/* implements CAD = 011 for the SSD1363 */
|
||||||
|
uint8_t u8x8_cad_011_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t *p;
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x000);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x040);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
p = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 24 )
|
||||||
|
{
|
||||||
|
u8x8_i2c_data_transfer(u8x8, 24, p);
|
||||||
|
arg_int-=24;
|
||||||
|
p+=24;
|
||||||
|
}
|
||||||
|
u8x8_i2c_data_transfer(u8x8, arg_int, p);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||||
|
if ( u8x8->i2c_address == 255 )
|
||||||
|
u8x8->i2c_address = 0x078;
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
/* cad transfer commands are ignored */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* fast version with reduced data start/stops, issue 735 */
|
||||||
|
uint8_t u8x8_cad_ssd13xx_fast_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
static uint8_t in_transfer = 0;
|
||||||
|
uint8_t *p;
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
/* improved version, takeover from ld7032 */
|
||||||
|
/* assumes, that the args of a command is not longer than 31 bytes */
|
||||||
|
/* speed improvement is about 4% compared to the classic version */
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x000); /* cmd byte for ssd13xx controller */
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
in_transfer = 1;
|
||||||
|
/* lightning version: can replace the improved version from above */
|
||||||
|
/* the drawback of the lightning version is this: The complete init sequence */
|
||||||
|
/* must fit into the 32 byte Arduino Wire buffer, which might not always be the case */
|
||||||
|
/* speed improvement is about 6% compared to the classic version */
|
||||||
|
// if ( in_transfer == 0 )
|
||||||
|
// {
|
||||||
|
// u8x8_byte_StartTransfer(u8x8);
|
||||||
|
// u8x8_byte_SendByte(u8x8, 0x000); /* cmd byte for ssd13xx controller */
|
||||||
|
// in_transfer = 1;
|
||||||
|
// }
|
||||||
|
//u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
|
||||||
|
|
||||||
|
/* the FeatherWing OLED with the 32u4 transfer of long byte */
|
||||||
|
/* streams was not possible. This is broken down to */
|
||||||
|
/* smaller streams, 32 seems to be the limit... */
|
||||||
|
/* I guess this is related to the size of the Wire buffers in Arduino */
|
||||||
|
/* Unfortunately, this can not be handled in the byte level drivers, */
|
||||||
|
/* so this is done here. Even further, only 24 bytes will be sent, */
|
||||||
|
/* because there will be another byte (DC) required during the transfer */
|
||||||
|
p = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 24 )
|
||||||
|
{
|
||||||
|
u8x8_i2c_data_transfer(u8x8, 24, p);
|
||||||
|
arg_int-=24;
|
||||||
|
p+=24;
|
||||||
|
}
|
||||||
|
u8x8_i2c_data_transfer(u8x8, arg_int, p);
|
||||||
|
in_transfer = 0;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||||
|
if ( u8x8->i2c_address == 255 )
|
||||||
|
u8x8->i2c_address = 0x078;
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
in_transfer = 0;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
in_transfer = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* the st75256 i2c driver is a copy of the ssd13xx driver, but with arg=1 */
|
||||||
|
/* modified from cad001 (ssd13xx) to cad011 */
|
||||||
|
uint8_t u8x8_cad_st75256_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t *p;
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x000);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x040);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
/* see ssd13xx driver */
|
||||||
|
p = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 24 )
|
||||||
|
{
|
||||||
|
u8x8_i2c_data_transfer(u8x8, 24, p);
|
||||||
|
arg_int-=24;
|
||||||
|
p+=24;
|
||||||
|
}
|
||||||
|
u8x8_i2c_data_transfer(u8x8, arg_int, p);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||||
|
if ( u8x8->i2c_address == 255 )
|
||||||
|
u8x8->i2c_address = 0x078; /* ST75256, often this is 0x07e */
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
/* cad transfer commands are ignored */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cad i2c procedure for the ld7032 controller */
|
||||||
|
/* Issue https://github.com/olikraus/u8g2/issues/865 mentiones, that I2C does not work */
|
||||||
|
/* Workaround is to remove the while loop (or increase the value in the condition) */
|
||||||
|
uint8_t u8x8_cad_ld7032_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
static uint8_t in_transfer = 0;
|
||||||
|
uint8_t *p;
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
in_transfer = 1;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
//u8x8_byte_SetDC(u8x8, 1);
|
||||||
|
|
||||||
|
/* the FeatherWing OLED with the 32u4 transfer of long byte */
|
||||||
|
/* streams was not possible. This is broken down to */
|
||||||
|
/* smaller streams, 32 seems to be the limit... */
|
||||||
|
/* I guess this is related to the size of the Wire buffers in Arduino */
|
||||||
|
/* Unfortunately, this can not be handled in the byte level drivers, */
|
||||||
|
/* so this is done here. Even further, only 24 bytes will be sent, */
|
||||||
|
/* because there will be another byte (DC) required during the transfer */
|
||||||
|
p = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 24 )
|
||||||
|
{
|
||||||
|
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
|
||||||
|
arg_int-=24;
|
||||||
|
p+=24;
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
u8x8_byte_SendByte(u8x8, 0x08); /* data write for LD7032 */
|
||||||
|
}
|
||||||
|
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||||
|
if ( u8x8->i2c_address == 255 )
|
||||||
|
u8x8->i2c_address = 0x060;
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
in_transfer = 0;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cad procedure for the UC16xx family in I2C mode */
|
||||||
|
/* u8x8_byte_SetDC is not used */
|
||||||
|
/* DC bit is encoded into the adr byte, structure is CAD001 */
|
||||||
|
uint8_t u8x8_cad_uc16xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
static uint8_t in_transfer = 0;
|
||||||
|
static uint8_t is_data = 0;
|
||||||
|
uint8_t *p;
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
{
|
||||||
|
if ( is_data != 0 )
|
||||||
|
{
|
||||||
|
/* transfer mode is active, but data transfer */
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
/* clear the lowest two bits of the adr */
|
||||||
|
u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc );
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* clear the lowest two bits of the adr */
|
||||||
|
u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc );
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
in_transfer = 1;
|
||||||
|
// is_data = 0; // 20 Jun 2021: I assume that this is missing here
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
{
|
||||||
|
if ( is_data == 0 )
|
||||||
|
{
|
||||||
|
/* transfer mode is active, but data transfer */
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
/* clear the lowest two bits of the adr */
|
||||||
|
u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* clear the lowest two bits of the adr */
|
||||||
|
u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
in_transfer = 1;
|
||||||
|
// is_data = 1; // 20 Jun 2021: I assume that this is missing here
|
||||||
|
|
||||||
|
p = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 24 )
|
||||||
|
{
|
||||||
|
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
|
||||||
|
arg_int-=24;
|
||||||
|
p+=24;
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||||
|
if ( u8x8->i2c_address == 255 )
|
||||||
|
u8x8->i2c_address = 0x070;
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
in_transfer = 0;
|
||||||
|
/* actual start is delayed, because we do not whether this is data or cmd transfer */
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
in_transfer = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cad procedure for the UC1638 in I2C mode */
|
||||||
|
/* same as u8x8_cad_uc16xx_i2c but CAD structure is CAD011 */
|
||||||
|
uint8_t u8x8_cad_uc1638_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
static uint8_t in_transfer = 0;
|
||||||
|
static uint8_t is_data = 0;
|
||||||
|
uint8_t *p;
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_CAD_SEND_CMD:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
{
|
||||||
|
if ( is_data != 0 )
|
||||||
|
{
|
||||||
|
/* transfer mode is active, but data transfer */
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
/* clear the lowest two bits of the adr */
|
||||||
|
u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc );
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* clear the lowest two bits of the adr */
|
||||||
|
u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc );
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
in_transfer = 1;
|
||||||
|
is_data = 0;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_ARG:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
{
|
||||||
|
if ( is_data == 0 )
|
||||||
|
{
|
||||||
|
/* transfer mode is active, but data transfer */
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
/* clear the lowest two bits of the adr */
|
||||||
|
u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* clear the lowest two bits of the adr */
|
||||||
|
u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
u8x8_byte_SendByte(u8x8, arg_int);
|
||||||
|
in_transfer = 1;
|
||||||
|
is_data = 1;
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_SEND_DATA:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
{
|
||||||
|
if ( is_data == 0 )
|
||||||
|
{
|
||||||
|
/* transfer mode is active, but data transfer */
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
/* clear the lowest two bits of the adr */
|
||||||
|
u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* clear the lowest two bits of the adr */
|
||||||
|
u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
in_transfer = 1;
|
||||||
|
is_data = 1;
|
||||||
|
|
||||||
|
p = (uint8_t *)arg_ptr;
|
||||||
|
while( arg_int > 24 )
|
||||||
|
{
|
||||||
|
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
|
||||||
|
arg_int-=24;
|
||||||
|
p+=24;
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
u8x8_byte_StartTransfer(u8x8);
|
||||||
|
}
|
||||||
|
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_INIT:
|
||||||
|
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||||
|
if ( u8x8->i2c_address == 255 )
|
||||||
|
u8x8->i2c_address = 0x078; /* see also https://github.com/olikraus/u8g2/issues/371 for a discussion on this value */
|
||||||
|
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
case U8X8_MSG_CAD_START_TRANSFER:
|
||||||
|
in_transfer = 0;
|
||||||
|
/* actual start is delayed, because we do not whether this is data or cmd transfer */
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_CAD_END_TRANSFER:
|
||||||
|
if ( in_transfer != 0 )
|
||||||
|
u8x8_byte_EndTransfer(u8x8);
|
||||||
|
in_transfer = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
254
main/utilities/u8g2/src/u8x8_capture.c
Normal file
254
main/utilities/u8g2/src/u8x8_capture.c
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_capture.c
|
||||||
|
|
||||||
|
Screen capture funcion
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
/*========================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
/* vertical top lsb memory architecture */
|
||||||
|
uint8_t u8x8_capture_get_pixel_1(uint16_t x, uint16_t y, uint8_t *dest_ptr, uint8_t tile_width)
|
||||||
|
{
|
||||||
|
//uint8_t *dest_ptr = capture->buffer;
|
||||||
|
//if ( dest_ptr == NULL )
|
||||||
|
//return 0;
|
||||||
|
//dest_ptr += (y/8)*capture->tile_width*8;
|
||||||
|
dest_ptr += (y/8)*tile_width*8;
|
||||||
|
y &= 7;
|
||||||
|
dest_ptr += x;
|
||||||
|
if ( (*dest_ptr & (1<<y)) == 0 )
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* horizontal right lsb memory architecture */
|
||||||
|
/* SH1122, LD7032, ST7920, ST7986, LC7981, T6963, SED1330, RA8835, MAX7219, LS0 */
|
||||||
|
uint8_t u8x8_capture_get_pixel_2(uint16_t x, uint16_t y, uint8_t *dest_ptr, uint8_t tile_width)
|
||||||
|
{
|
||||||
|
//uint8_t *dest_ptr = capture->buffer;
|
||||||
|
//if ( dest_ptr == NULL )
|
||||||
|
// return 0;
|
||||||
|
//dest_ptr += y*capture->tile_width;
|
||||||
|
y *= tile_width;
|
||||||
|
dest_ptr += y;
|
||||||
|
dest_ptr += x>>3;
|
||||||
|
if ( (*dest_ptr & (128>>(x&7))) == 0 )
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_capture_write_pbm_pre(uint8_t tile_width, uint8_t tile_height, void (*out)(const char *s))
|
||||||
|
{
|
||||||
|
out("P1\n");
|
||||||
|
out(u8x8_utoa((uint16_t)tile_width*8));
|
||||||
|
out("\n");
|
||||||
|
out(u8x8_utoa((uint16_t)tile_height*8));
|
||||||
|
out("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void u8x8_capture_write_pbm_buffer(uint8_t *buffer, uint8_t tile_width, uint8_t tile_height, uint8_t (*get_pixel)(uint16_t x, uint16_t y, uint8_t *dest_ptr, uint8_t tile_width), void (*out)(const char *s))
|
||||||
|
{
|
||||||
|
uint16_t x, y;
|
||||||
|
uint16_t w, h;
|
||||||
|
|
||||||
|
w = tile_width;
|
||||||
|
w *= 8;
|
||||||
|
h = tile_height;
|
||||||
|
h *= 8;
|
||||||
|
|
||||||
|
for( y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
for( x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
if ( get_pixel(x, y, buffer, tile_width) )
|
||||||
|
out("1");
|
||||||
|
else
|
||||||
|
out("0");
|
||||||
|
}
|
||||||
|
out("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void u8x8_capture_write_xbm_pre(uint8_t tile_width, uint8_t tile_height, void (*out)(const char *s))
|
||||||
|
{
|
||||||
|
out("#define xbm_width ");
|
||||||
|
out(u8x8_utoa((uint16_t)tile_width*8));
|
||||||
|
out("\n");
|
||||||
|
out("#define xbm_height ");
|
||||||
|
out(u8x8_utoa((uint16_t)tile_height*8));
|
||||||
|
out("\n");
|
||||||
|
out("static unsigned char xbm_bits[] = {\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_capture_write_xbm_buffer(uint8_t *buffer, uint8_t tile_width, uint8_t tile_height, uint8_t (*get_pixel)(uint16_t x, uint16_t y, uint8_t *dest_ptr, uint8_t tile_width), void (*out)(const char *s))
|
||||||
|
{
|
||||||
|
uint16_t x, y;
|
||||||
|
uint16_t w, h;
|
||||||
|
uint8_t v, b;
|
||||||
|
char s[2];
|
||||||
|
s[1] = '\0';
|
||||||
|
|
||||||
|
w = tile_width;
|
||||||
|
w *= 8;
|
||||||
|
h = tile_height;
|
||||||
|
h *= 8;
|
||||||
|
|
||||||
|
y = 0;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
v = 0;
|
||||||
|
for( b = 0; b < 8; b++ )
|
||||||
|
{
|
||||||
|
v <<= 1;
|
||||||
|
if ( get_pixel(x+7-b, y, buffer, tile_width) )
|
||||||
|
v |= 1;
|
||||||
|
}
|
||||||
|
out("0x");
|
||||||
|
s[0] = (v>>4);
|
||||||
|
if ( s[0] <= 9 )
|
||||||
|
s[0] += '0';
|
||||||
|
else
|
||||||
|
s[0] += 'a'-10;
|
||||||
|
out(s);
|
||||||
|
s[0] = (v&15);
|
||||||
|
if ( s[0] <= 9 )
|
||||||
|
s[0] += '0';
|
||||||
|
else
|
||||||
|
s[0] += 'a'-10;
|
||||||
|
out(s);
|
||||||
|
x += 8;
|
||||||
|
if ( x >= w )
|
||||||
|
break;
|
||||||
|
out(",");
|
||||||
|
}
|
||||||
|
y++;
|
||||||
|
if ( y >= h )
|
||||||
|
break;
|
||||||
|
out(",");
|
||||||
|
out("\n");
|
||||||
|
}
|
||||||
|
out("};\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*========================================================*/
|
||||||
|
|
||||||
|
#ifdef NOT_YET_IMPLEMENTED_U8X8_SCREEN_CAPTURE
|
||||||
|
|
||||||
|
struct _u8x8_capture_struct
|
||||||
|
{
|
||||||
|
u8x8_msg_cb old_cb;
|
||||||
|
uint8_t *buffer; /* tile_width*tile_height*8 bytes */
|
||||||
|
uint8_t tile_width;
|
||||||
|
uint8_t tile_height;
|
||||||
|
};
|
||||||
|
typedef struct _u8x8_capture_struct u8x8_capture_t;
|
||||||
|
|
||||||
|
|
||||||
|
u8x8_capture_t u8x8_capture;
|
||||||
|
|
||||||
|
|
||||||
|
static void u8x8_capture_memory_copy(uint8_t *dest, uint8_t *src, uint16_t cnt)
|
||||||
|
{
|
||||||
|
while( cnt > 0 )
|
||||||
|
{
|
||||||
|
*dest++ = *src++;
|
||||||
|
cnt--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void u8x8_capture_DrawTiles(u8x8_capture_t *capture, uint8_t tx, uint8_t ty, uint8_t tile_cnt, uint8_t *tile_ptr)
|
||||||
|
{
|
||||||
|
uint8_t *dest_ptr = capture->buffer;
|
||||||
|
//printf("tile pos: %d %d, cnt=%d\n", tx, ty, tile_cnt);
|
||||||
|
if ( dest_ptr == NULL )
|
||||||
|
return;
|
||||||
|
dest_ptr += (uint16_t)ty*capture->tile_width*8;
|
||||||
|
dest_ptr += (uint16_t)tx*8;
|
||||||
|
u8x8_capture_memory_copy(dest_ptr, tile_ptr, tile_cnt*8);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_d_capture(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
if ( msg == U8X8_MSG_DISPLAY_DRAW_TILE )
|
||||||
|
{
|
||||||
|
uint8_t x, y, c;
|
||||||
|
uint8_t *ptr;
|
||||||
|
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||||
|
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
|
||||||
|
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||||
|
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8x8_capture_DrawTiles(&u8x8_capture, x, y, c, ptr);
|
||||||
|
x += c;
|
||||||
|
arg_int--;
|
||||||
|
} while( arg_int > 0 );
|
||||||
|
}
|
||||||
|
return u8x8_capture.old_cb(u8x8, msg, arg_int, arg_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_GetCaptureMemoryPixel(u8x8_t *u8x8, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
return u8x8_capture_GetPixel(&u8x8_capture, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* memory: tile_width*tile_height*8 bytes */
|
||||||
|
void u8x8_ConnectCapture(u8x8_t *u8x8, uint8_t tile_width, uint8_t tile_height, uint8_t *memory)
|
||||||
|
{
|
||||||
|
if ( u8x8->display_cb == u8x8_d_capture )
|
||||||
|
return; /* do nothing, capture already installed */
|
||||||
|
|
||||||
|
u8x8_capture.buffer = memory; /* tile_width*tile_height*8 bytes */
|
||||||
|
u8x8_capture.tile_width = tile_width;
|
||||||
|
u8x8_capture.tile_height = tile_height;
|
||||||
|
u8x8_capture.old_cb = u8x8->display_cb;
|
||||||
|
u8x8->display_cb = u8x8_d_capture;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
544
main/utilities/u8g2/src/u8x8_d_ssd1306_128x64_noname.c
Normal file
544
main/utilities/u8g2/src/u8x8_d_ssd1306_128x64_noname.c
Normal file
@ -0,0 +1,544 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_d_ssd1306_128x64_noname.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* more or less generic setup of all these small OLEDs */
|
||||||
|
static const uint8_t u8x8_d_ssd1306_128x64_noname_init_seq[] = {
|
||||||
|
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
|
||||||
|
|
||||||
|
U8X8_C(0x0ae), /* display off */
|
||||||
|
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||||
|
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
|
||||||
|
U8X8_CA(0x0d3, 0x000), /* display offset */
|
||||||
|
U8X8_C(0x040), /* set display start line to 0 */
|
||||||
|
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, SSD1306 only, should be removed for SH1106 */
|
||||||
|
U8X8_CA(0x020, 0x000), /* horizontal addressing mode */
|
||||||
|
|
||||||
|
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||||
|
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||||
|
// Flipmode
|
||||||
|
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||||
|
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||||
|
|
||||||
|
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||||
|
|
||||||
|
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control */
|
||||||
|
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
|
||||||
|
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
|
||||||
|
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
|
||||||
|
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
|
||||||
|
|
||||||
|
U8X8_C(0x02e), /* Deactivate scroll */
|
||||||
|
U8X8_C(0x0a4), /* output ram to display */
|
||||||
|
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||||
|
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* this setup maximizes the brightness range, that can be set with setContrast() */
|
||||||
|
/* Drawback: VCOMH deselect level is set to 0, which das not work so good with all OLEDs, issue #116 */
|
||||||
|
static const uint8_t u8x8_d_ssd1306_128x64_vcomh0_init_seq[] = {
|
||||||
|
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
|
||||||
|
|
||||||
|
U8X8_C(0x0ae), /* display off */
|
||||||
|
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||||
|
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
|
||||||
|
U8X8_CA(0x0d3, 0x000), /* display offset */
|
||||||
|
U8X8_C(0x040), /* set display start line to 0 */
|
||||||
|
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */
|
||||||
|
U8X8_CA(0x020, 0x000), /* horizontal addressing mode */
|
||||||
|
|
||||||
|
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||||
|
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||||
|
// Flipmode
|
||||||
|
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||||
|
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||||
|
|
||||||
|
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||||
|
U8X8_CA(0x081, 0x0ef), /* [2] set contrast control, */
|
||||||
|
U8X8_CA(0x0d9, 0x0a1), /* [2] pre-charge period 0x022/f1*/
|
||||||
|
U8X8_CA(0x0db, 0x000), /* vcomh deselect level 0x000 .. 0x070, low nibble always 0 */
|
||||||
|
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
|
||||||
|
|
||||||
|
U8X8_C(0x02e), /* Deactivate scroll */
|
||||||
|
U8X8_C(0x0a4), /* output ram to display */
|
||||||
|
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||||
|
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* same as u8x8_d_ssd1306_128x64_noname_init_seq, but 0x0da bit 4 is set to 0 */
|
||||||
|
/* this will disable the alternative COM configuration */
|
||||||
|
static const uint8_t u8x8_d_ssd1306_128x64_alt0_init_seq[] = {
|
||||||
|
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
|
||||||
|
|
||||||
|
U8X8_C(0x0ae), /* display off */
|
||||||
|
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||||
|
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
|
||||||
|
U8X8_CA(0x0d3, 0x000), /* display offset */
|
||||||
|
U8X8_C(0x040), /* set display start line to 0 */
|
||||||
|
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, SSD1306 only, should be removed for SH1106 */
|
||||||
|
U8X8_CA(0x020, 0x000), /* horizontal addressing mode */
|
||||||
|
|
||||||
|
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||||
|
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||||
|
// Flipmode
|
||||||
|
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||||
|
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||||
|
|
||||||
|
U8X8_CA(0x0da, 0x002), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||||
|
|
||||||
|
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control */
|
||||||
|
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
|
||||||
|
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
|
||||||
|
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
|
||||||
|
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
|
||||||
|
|
||||||
|
U8X8_C(0x02e), /* Deactivate scroll */
|
||||||
|
U8X8_C(0x0a4), /* output ram to display */
|
||||||
|
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||||
|
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* issue 316: a special sh1106 setup, https://www.mikrocontroller.net/topic/431371?goto=5087807#5087807 */
|
||||||
|
static const uint8_t u8x8_d_sh1106_128x64_winstar_init_seq[] = {
|
||||||
|
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
|
||||||
|
U8X8_C(0xae), // Display OFF/ON: off (POR = 0xae)
|
||||||
|
U8X8_C(0xa4), // Set Entire Display OFF/ON: off (POR = 0xa4)
|
||||||
|
U8X8_CA(0xd5, 0x50), // Divide Ratio/Oscillator FrequencyData Set: divide ratio = 1 (POR = 1), Oscillator Frequency = +/- 0% (POR = +/- 0%)
|
||||||
|
U8X8_CA(0xa8, 0x3f), // Multiplex Ratio Data Set: 64 (POR = 0x3f, 64)
|
||||||
|
U8X8_CA(0xd3, 0x00), // Display OffsetData Set: 0 (POR = 0x00)
|
||||||
|
U8X8_C(0x40), // Set Display Start Line: 0
|
||||||
|
U8X8_CA(0xad, 0x8b), // DC-DC ON/OFF Mode Set: Built-in DC-DC is used, Normal Display (POR = 0x8b)
|
||||||
|
U8X8_CA(0xd9, 0x22), // Dis-charge/Pre-charge PeriodData Set: pre-charge 2 DCLKs, dis-charge 2 DCLKs (POR = 0x22, pre-charge 2 DCLKs, dis-charge 2 DCLKs)
|
||||||
|
U8X8_CA(0xdb, 0x35), // VCOM Deselect LevelData Set: 0,770V (POR = 0x35, 0,770 V)
|
||||||
|
U8X8_C(0x32), // Set Pump voltage value: 8,0 V (POR = 0x32, 8,0 V)
|
||||||
|
U8X8_CA(0x81, 0xff), // Contrast Data Register Set: 255 (large) (POR = 0x80)
|
||||||
|
U8X8_C(0x0a6), // Set Normal/Reverse Display: normal (POR = 0xa6)
|
||||||
|
U8X8_CA(0x0da, 0x012), // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5)
|
||||||
|
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t u8x8_d_ssd1312_128x64_noname_init_seq[] = {
|
||||||
|
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
|
||||||
|
|
||||||
|
U8X8_C(0x0ae), /* display off */
|
||||||
|
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||||
|
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
|
||||||
|
U8X8_CA(0x0d3, 0x000), /* display offset */
|
||||||
|
U8X8_C(0x040), /* set display start line to 0 */
|
||||||
|
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, SSD1306 only, should be removed for SH1106 */
|
||||||
|
U8X8_CA(0x020, 0x000), /* horizontal addressing mode */
|
||||||
|
|
||||||
|
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||||
|
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||||
|
|
||||||
|
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||||
|
|
||||||
|
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control */
|
||||||
|
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
|
||||||
|
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
|
||||||
|
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
|
||||||
|
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
|
||||||
|
|
||||||
|
U8X8_C(0x02e), /* Deactivate scroll */
|
||||||
|
U8X8_C(0x0a4), /* output ram to display */
|
||||||
|
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||||
|
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const uint8_t u8x8_d_ssd1306_128x64_noname_powersave0_seq[] = {
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
U8X8_C(0x0af), /* display on */
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t u8x8_d_ssd1306_128x64_noname_powersave1_seq[] = {
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
U8X8_C(0x0ae), /* display off */
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t u8x8_d_ssd1306_128x64_noname_flip0_seq[] = {
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||||
|
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t u8x8_d_ssd1306_128x64_noname_flip1_seq[] = {
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||||
|
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t u8x8_d_ssd1312_128x64_noname_flip0_seq[] = {
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||||
|
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t u8x8_d_ssd1312_128x64_noname_flip1_seq[] = {
|
||||||
|
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||||
|
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||||
|
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||||
|
U8X8_END_TRANSFER(), /* disable chip */
|
||||||
|
U8X8_END() /* end of sequence */
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t u8x8_d_ssd1306_sh1106_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
uint8_t x, c;
|
||||||
|
uint8_t *ptr;
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
/* handled by the calling function
|
||||||
|
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||||
|
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
/* handled by the calling function
|
||||||
|
case U8X8_MSG_DISPLAY_INIT:
|
||||||
|
u8x8_d_helper_display_init(u8x8);
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||||
|
if ( arg_int == 0 )
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_powersave0_seq);
|
||||||
|
else
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_powersave1_seq);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||||
|
if ( arg_int == 0 )
|
||||||
|
{
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_flip0_seq);
|
||||||
|
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_flip1_seq);
|
||||||
|
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifdef U8X8_WITH_SET_CONTRAST
|
||||||
|
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||||
|
u8x8_cad_StartTransfer(u8x8);
|
||||||
|
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||||
|
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
|
||||||
|
u8x8_cad_EndTransfer(u8x8);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||||
|
u8x8_cad_StartTransfer(u8x8);
|
||||||
|
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||||
|
x *= 8;
|
||||||
|
x += u8x8->x_offset;
|
||||||
|
|
||||||
|
u8x8_cad_SendCmd(u8x8, 0x040 ); /* set line offset to 0 */
|
||||||
|
|
||||||
|
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||||
|
u8x8_cad_SendArg(u8x8, 0x000 | ((x&15))); /* probably wrong, should be SendCmd */
|
||||||
|
u8x8_cad_SendArg(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos)); /* probably wrong, should be SendCmd */
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||||
|
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||||
|
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||||
|
/*
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8x8_cad_SendData(u8x8, 8, ptr);
|
||||||
|
ptr += 8;
|
||||||
|
c--;
|
||||||
|
} while( c > 0 );
|
||||||
|
*/
|
||||||
|
arg_int--;
|
||||||
|
} while( arg_int > 0 );
|
||||||
|
|
||||||
|
u8x8_cad_EndTransfer(u8x8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const u8x8_display_info_t u8x8_ssd1306_128x64_noname_display_info =
|
||||||
|
{
|
||||||
|
/* chip_enable_level = */ 0,
|
||||||
|
/* chip_disable_level = */ 1,
|
||||||
|
|
||||||
|
/* post_chip_enable_wait_ns = */ 20,
|
||||||
|
/* pre_chip_disable_wait_ns = */ 10,
|
||||||
|
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||||
|
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||||
|
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||||
|
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||||
|
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||||
|
/* spi_mode = */ 0, /* active high, rising edge */
|
||||||
|
/* i2c_bus_clock_100kHz = */ 4,
|
||||||
|
/* data_setup_time_ns = */ 40,
|
||||||
|
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||||
|
/* tile_width = */ 16,
|
||||||
|
/* tile_height = */ 8,
|
||||||
|
/* default_x_offset = */ 0,
|
||||||
|
/* flipmode_x_offset = */ 0,
|
||||||
|
/* pixel_width = */ 128,
|
||||||
|
/* pixel_height = */ 64
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t u8x8_d_ssd1306_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_DISPLAY_INIT:
|
||||||
|
u8x8_d_helper_display_init(u8x8);
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||||
|
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_d_ssd1312_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||||
|
if ( arg_int == 0 )
|
||||||
|
{
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_128x64_noname_flip0_seq);
|
||||||
|
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_128x64_noname_flip1_seq);
|
||||||
|
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DISPLAY_INIT:
|
||||||
|
u8x8_d_helper_display_init(u8x8);
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_128x64_noname_init_seq); /* update 27 mar 2022 */
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||||
|
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t u8x8_d_ssd1306_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_DISPLAY_INIT:
|
||||||
|
u8x8_d_helper_display_init(u8x8);
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_vcomh0_init_seq);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||||
|
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_d_ssd1306_128x64_alt0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_DISPLAY_INIT:
|
||||||
|
u8x8_d_helper_display_init(u8x8);
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_alt0_init_seq);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||||
|
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const u8x8_display_info_t u8x8_sh1106_128x64_noname_display_info =
|
||||||
|
{
|
||||||
|
/* chip_enable_level = */ 0,
|
||||||
|
/* chip_disable_level = */ 1,
|
||||||
|
|
||||||
|
/* post_chip_enable_wait_ns = */ 20,
|
||||||
|
/* pre_chip_disable_wait_ns = */ 10,
|
||||||
|
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||||
|
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||||
|
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||||
|
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||||
|
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
|
||||||
|
/* spi_mode = */ 0, /* issue 1901: changed mode from 3 to 0 */
|
||||||
|
/* i2c_bus_clock_100kHz = */ 4,
|
||||||
|
/* data_setup_time_ns = */ 40,
|
||||||
|
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||||
|
/* tile_width = */ 16,
|
||||||
|
/* tile_height = */ 8,
|
||||||
|
/* default_x_offset = */ 2,
|
||||||
|
/* flipmode_x_offset = */ 2,
|
||||||
|
/* pixel_width = */ 128,
|
||||||
|
/* pixel_height = */ 64
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t u8x8_d_sh1106_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_DISPLAY_INIT:
|
||||||
|
u8x8_d_helper_display_init(u8x8);
|
||||||
|
/* maybe use a better init sequence */
|
||||||
|
/* https://www.mikrocontroller.net/topic/431371 */
|
||||||
|
/* the new sequence is added in the winstar constructor (see below), this is kept untouched */
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||||
|
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_128x64_noname_display_info);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_d_sh1106_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_DISPLAY_INIT:
|
||||||
|
u8x8_d_helper_display_init(u8x8);
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_vcomh0_init_seq);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||||
|
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_128x64_noname_display_info);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t u8x8_d_sh1106_128x64_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||||
|
{
|
||||||
|
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_DISPLAY_INIT:
|
||||||
|
u8x8_d_helper_display_init(u8x8);
|
||||||
|
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_128x64_winstar_init_seq);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||||
|
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_128x64_noname_display_info);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
205
main/utilities/u8g2/src/u8x8_debounce.c
Normal file
205
main/utilities/u8g2/src/u8x8_debounce.c
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_debounce.c
|
||||||
|
|
||||||
|
Key/button simple debounce algorithm (Addon for u8x8)
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
static uint8_t u8x8_read_pin_state(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t pin_state;
|
||||||
|
|
||||||
|
pin_state = 255; /* be compatible with the setup of the default pin setup, which is 255 */
|
||||||
|
for( i = 0; i < U8X8_PIN_INPUT_CNT; i++ )
|
||||||
|
{
|
||||||
|
pin_state <<= 1;
|
||||||
|
|
||||||
|
/* the callback function should put the return value into this variable */
|
||||||
|
u8x8->gpio_result = 1;
|
||||||
|
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO(i+U8X8_PIN_OUTPUT_CNT), 0);
|
||||||
|
pin_state |= u8x8->gpio_result & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pin_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
return 0 to U8X8_PIN_INPUT_CNT-1 if there is a difference
|
||||||
|
return U8X8_PIN_INPUT_CNT if there is no difference
|
||||||
|
*/
|
||||||
|
static uint8_t u8x8_find_first_diff(uint8_t a, uint8_t b)
|
||||||
|
{
|
||||||
|
uint8_t mask;
|
||||||
|
uint8_t i;
|
||||||
|
mask = 1;
|
||||||
|
i = U8X8_PIN_INPUT_CNT;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
if ( (a & mask) != (b & mask) )
|
||||||
|
return i;
|
||||||
|
mask <<= 1;
|
||||||
|
} while( i > 0 );
|
||||||
|
return U8X8_PIN_INPUT_CNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
State A:
|
||||||
|
u8x8->debounce_last_pin_state == current_state
|
||||||
|
--> State A
|
||||||
|
u8x8->debounce_last_pin_state != current_state
|
||||||
|
--> u8x8->debounce_last_pin_state = current_state
|
||||||
|
--> State B + cnt
|
||||||
|
|
||||||
|
State B + cnt
|
||||||
|
--> state--
|
||||||
|
|
||||||
|
State B
|
||||||
|
u8x8->debounce_last_pin_state == current_state
|
||||||
|
--> keypress detected
|
||||||
|
--> State C
|
||||||
|
u8x8->debounce_last_pin_state != current_state
|
||||||
|
--> State A
|
||||||
|
|
||||||
|
State C
|
||||||
|
u8x8->debounce_last_pin_state == current_state
|
||||||
|
--> State C
|
||||||
|
u8x8->debounce_last_pin_state != current_state
|
||||||
|
--> State A
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __unix__xxxxxx_THIS_IS_DISABLED
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
c = getc(stdin);
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case 'n':
|
||||||
|
return U8X8_MSG_GPIO_MENU_NEXT;
|
||||||
|
case 'p':
|
||||||
|
return U8X8_MSG_GPIO_MENU_PREV;
|
||||||
|
case 's':
|
||||||
|
return U8X8_MSG_GPIO_MENU_SELECT;
|
||||||
|
case 'h':
|
||||||
|
return U8X8_MSG_GPIO_MENU_HOME;
|
||||||
|
case 'x':
|
||||||
|
exit(0);
|
||||||
|
default:
|
||||||
|
puts("press n, p, s, h or x");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else /* __unix__ */
|
||||||
|
|
||||||
|
|
||||||
|
#define U8X8_DEBOUNCE_WAIT 2
|
||||||
|
/* do debounce and return a GPIO msg which indicates the event */
|
||||||
|
/* returns 0, if there is no event */
|
||||||
|
#if defined(__GNUC__) && !defined(_WIN32)
|
||||||
|
# pragma weak u8x8_GetMenuEvent
|
||||||
|
#endif
|
||||||
|
uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
uint8_t pin_state;
|
||||||
|
uint8_t result_msg = 0; /* invalid message, no event */
|
||||||
|
|
||||||
|
pin_state = u8x8_read_pin_state(u8x8);
|
||||||
|
|
||||||
|
/* States A, B, C & D are encoded in the upper 4 bit*/
|
||||||
|
switch(u8x8->debounce_state)
|
||||||
|
{
|
||||||
|
case 0x00: /* State A, default state */
|
||||||
|
if ( u8x8->debounce_default_pin_state != pin_state )
|
||||||
|
{
|
||||||
|
//u8x8->debounce_last_pin_state = pin_state;
|
||||||
|
u8x8->debounce_state = 0x010 + U8X8_DEBOUNCE_WAIT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x10: /* State B */
|
||||||
|
//if ( u8x8->debounce_last_pin_state != pin_state )
|
||||||
|
if ( u8x8->debounce_default_pin_state == pin_state )
|
||||||
|
{
|
||||||
|
u8x8->debounce_state = 0x00; /* back to state A */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* keypress detected */
|
||||||
|
u8x8->debounce_last_pin_state = pin_state;
|
||||||
|
//result_msg = U8X8_MSG_GPIO_MENU_NEXT;
|
||||||
|
u8x8->debounce_state = 0x020 + U8X8_DEBOUNCE_WAIT; /* got to state C */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x20: /* State C */
|
||||||
|
if ( u8x8->debounce_last_pin_state != pin_state )
|
||||||
|
{
|
||||||
|
u8x8->debounce_state = 0x00; /* back to state A */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8x8->debounce_state = 0x030; /* got to state D */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x30: /* State D */
|
||||||
|
/* wait until key release */
|
||||||
|
if ( u8x8->debounce_default_pin_state == pin_state )
|
||||||
|
{
|
||||||
|
u8x8->debounce_state = 0x00; /* back to state A */
|
||||||
|
result_msg = U8X8_MSG_GPIO(u8x8_find_first_diff(u8x8->debounce_default_pin_state, u8x8->debounce_last_pin_state)+U8X8_PIN_OUTPUT_CNT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//result_msg = U8X8_MSG_GPIO_MENU_NEXT;
|
||||||
|
// maybe implement autorepeat here
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
u8x8->debounce_state--; /* count down, until there is a valid state */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __unix__ */
|
||||||
203
main/utilities/u8g2/src/u8x8_display.c
Normal file
203
main/utilities/u8g2/src/u8x8_display.c
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_display.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
Abstraction layer for the graphics controller.
|
||||||
|
Main goal is the placement of a 8x8 pixel block (tile) on the display.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*==========================================*/
|
||||||
|
/* internal library function */
|
||||||
|
|
||||||
|
/*
|
||||||
|
this is a helper function for the U8X8_MSG_DISPLAY_SETUP_MEMORY function.
|
||||||
|
It can be called within the display callback function to carry out the usual standard tasks.
|
||||||
|
|
||||||
|
*/
|
||||||
|
void u8x8_d_helper_display_setup_memory(u8x8_t *u8x8, const u8x8_display_info_t *display_info)
|
||||||
|
{
|
||||||
|
/* 1) set display info struct */
|
||||||
|
u8x8->display_info = display_info;
|
||||||
|
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
this is a helper function for the U8X8_MSG_DISPLAY_INIT function.
|
||||||
|
It can be called within the display callback function to carry out the usual standard tasks.
|
||||||
|
|
||||||
|
*/
|
||||||
|
void u8x8_d_helper_display_init(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
/* 2) apply port directions to the GPIO lines and apply default values for the IO lines*/
|
||||||
|
u8x8_gpio_Init(u8x8); /* macro, which calls gpio_and_delay_cb with U8X8_MSG_GPIO_AND_DELAY_INIT */
|
||||||
|
u8x8_cad_Init(u8x8); /* this will also call U8X8_MSG_BYTE_INIT, byte init will NOT call GPIO_INIT */
|
||||||
|
|
||||||
|
/* 3) do reset */
|
||||||
|
u8x8_gpio_SetReset(u8x8, 1);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms);
|
||||||
|
u8x8_gpio_SetReset(u8x8, 0);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms);
|
||||||
|
u8x8_gpio_SetReset(u8x8, 1);
|
||||||
|
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->post_reset_wait_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==========================================*/
|
||||||
|
/* official functions */
|
||||||
|
|
||||||
|
uint8_t u8x8_DrawTile(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_ptr)
|
||||||
|
{
|
||||||
|
u8x8_tile_t tile;
|
||||||
|
tile.x_pos = x;
|
||||||
|
tile.y_pos = y;
|
||||||
|
tile.cnt = cnt;
|
||||||
|
tile.tile_ptr = tile_ptr;
|
||||||
|
return u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, 1, (void *)&tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* should be implemented as macro */
|
||||||
|
void u8x8_SetupMemory(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SETUP_MEMORY, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This will just init the display interface, compared to InitDisplay, it will not issue a reset and also not upload the init code.
|
||||||
|
Comparison:
|
||||||
|
Call u8x8_InitInterface u8x8_InitDisplay
|
||||||
|
Init Interface yes yes
|
||||||
|
Reset Display no yes
|
||||||
|
Upload Display Init Code no yes
|
||||||
|
|
||||||
|
u8x8_InitInterface() is an alternative function to u8x8_InitDisplay(). Do not call both.
|
||||||
|
|
||||||
|
*/
|
||||||
|
void u8x8_InitInterface(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
u8x8_gpio_Init(u8x8); /* macro, which calls gpio_and_delay_cb with U8X8_MSG_GPIO_AND_DELAY_INIT */
|
||||||
|
u8x8_cad_Init(u8x8); /* this will also call U8X8_MSG_BYTE_INIT, byte init will NOT call GPIO_INIT, which alread is called in the prev step */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This will sent the display init message to the display.
|
||||||
|
The display itself will then call u8x8_d_helper_display_init() from above. This includes:
|
||||||
|
GPIO Init (set port directions)
|
||||||
|
BYTE init (part of CAD init: which may set some levels)
|
||||||
|
CAD init (which will set things like I2C default address)
|
||||||
|
Issue a reset to the display: This will usually turn off the display
|
||||||
|
Additonally each display will set the init code to the display, which will also turn of the display in most cases (Arduino code disable power save mode later)
|
||||||
|
|
||||||
|
Actually this procedure should be better called InitInterfaceAndDisplay, because it actually does both.
|
||||||
|
(actually u8x8_InitInterface() is not called directly but only u8x8_gpio_Init and u8x8_cad_Init which
|
||||||
|
in turn is called by u8x8_InitInterface())
|
||||||
|
|
||||||
|
|
||||||
|
InitDisplay is called by the Arduino begin() function
|
||||||
|
|
||||||
|
In some cases it is not required to init the display (for example if the display is already running, but the controller comes out of deep sleep mode).
|
||||||
|
Then InitDisplay can be skipped, but u8x8_InitInterface() (== u8x8_gpio_Init() and u8x8_cad_Init()) need to be executed.
|
||||||
|
|
||||||
|
*/
|
||||||
|
void u8x8_InitDisplay(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL); /* this will call u8x8_d_helper_display_init() and send the init seqence to the display */
|
||||||
|
/* u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_FLIP_MODE, 0, NULL); */ /* It would make sense to call flip mode 0 here after U8X8_MSG_DISPLAY_INIT */
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable)
|
||||||
|
{
|
||||||
|
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_POWER_SAVE, is_enable, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_SetFlipMode(u8x8_t *u8x8, uint8_t mode)
|
||||||
|
{
|
||||||
|
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_FLIP_MODE, mode, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_SetContrast(u8x8_t *u8x8, uint8_t value)
|
||||||
|
{
|
||||||
|
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_CONTRAST, value, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_RefreshDisplay(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_REFRESH, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_ClearDisplayWithTile(u8x8_t *u8x8, const uint8_t *buf)
|
||||||
|
{
|
||||||
|
u8x8_tile_t tile;
|
||||||
|
uint8_t h;
|
||||||
|
|
||||||
|
tile.x_pos = 0;
|
||||||
|
tile.cnt = 1;
|
||||||
|
tile.tile_ptr = (uint8_t *)buf; /* tile_ptr should be const, but isn't */
|
||||||
|
|
||||||
|
h = u8x8->display_info->tile_height;
|
||||||
|
tile.y_pos = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile);
|
||||||
|
tile.y_pos++;
|
||||||
|
} while( tile.y_pos < h );
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_ClearDisplay(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
u8x8_ClearDisplayWithTile(u8x8, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_FillDisplay(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
uint8_t buf[8] = { 255, 255, 255, 255, 255, 255, 255, 255 };
|
||||||
|
u8x8_ClearDisplayWithTile(u8x8, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_ClearLine(u8x8_t *u8x8, uint8_t line)
|
||||||
|
{
|
||||||
|
uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
u8x8_tile_t tile;
|
||||||
|
if ( line < u8x8->display_info->tile_height )
|
||||||
|
{
|
||||||
|
tile.x_pos = 0;
|
||||||
|
tile.y_pos = line;
|
||||||
|
tile.cnt = 1;
|
||||||
|
tile.tile_ptr = (uint8_t *)buf; /* tile_ptr should be const, but isn't */
|
||||||
|
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
19833
main/utilities/u8g2/src/u8x8_fonts.c
Normal file
19833
main/utilities/u8g2/src/u8x8_fonts.c
Normal file
File diff suppressed because it is too large
Load Diff
50
main/utilities/u8g2/src/u8x8_gpio.c
Normal file
50
main/utilities/u8g2/src/u8x8_gpio.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_gpio.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
|
||||||
|
void u8x8_gpio_call(u8x8_t *u8x8, uint8_t msg, uint8_t arg)
|
||||||
|
{
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, msg, arg, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void u8x8_gpio_Delay(u8x8_t *u8x8, uint8_t msg, uint8_t dly)
|
||||||
|
{
|
||||||
|
u8x8->gpio_and_delay_cb(u8x8, msg, dly, NULL);
|
||||||
|
}
|
||||||
|
*/
|
||||||
123
main/utilities/u8g2/src/u8x8_input_value.c
Normal file
123
main/utilities/u8g2/src/u8x8_input_value.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_input_value.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
return:
|
||||||
|
0: value is not changed (HOME/Break Button pressed)
|
||||||
|
1: value has been updated
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint8_t u8x8_UserInterfaceInputValue(u8x8_t *u8x8, const char *title, const char *pre, uint8_t *value, uint8_t lo, uint8_t hi, uint8_t digits, const char *post)
|
||||||
|
{
|
||||||
|
uint8_t height;
|
||||||
|
uint8_t y;
|
||||||
|
uint8_t width;
|
||||||
|
uint8_t x;
|
||||||
|
uint8_t local_value = *value;
|
||||||
|
uint8_t r;
|
||||||
|
uint8_t event;
|
||||||
|
|
||||||
|
/* calculate overall height of the input value box */
|
||||||
|
height = 1; /* button line */
|
||||||
|
height += u8x8_GetStringLineCnt(title);
|
||||||
|
|
||||||
|
/* calculate offset from top */
|
||||||
|
y = 0;
|
||||||
|
if ( height < u8x8_GetRows(u8x8) )
|
||||||
|
{
|
||||||
|
y = u8x8_GetRows(u8x8);
|
||||||
|
y -= height;
|
||||||
|
y /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate offset from left for the label */
|
||||||
|
x = 0;
|
||||||
|
width = u8x8_GetUTF8Len(u8x8, pre);
|
||||||
|
width += digits;
|
||||||
|
width += u8x8_GetUTF8Len(u8x8, post);
|
||||||
|
if ( width < u8x8_GetCols(u8x8) )
|
||||||
|
{
|
||||||
|
x = u8x8_GetCols(u8x8);
|
||||||
|
x -= width;
|
||||||
|
x /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* render */
|
||||||
|
u8x8_ClearDisplay(u8x8); /* required, because not everything is filled */
|
||||||
|
u8x8_SetInverseFont(u8x8, 0);
|
||||||
|
y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title);
|
||||||
|
x += u8x8_DrawUTF8(u8x8, x, y, pre);
|
||||||
|
u8x8_DrawUTF8(u8x8, x+digits, y, post);
|
||||||
|
u8x8_SetInverseFont(u8x8, 1);
|
||||||
|
|
||||||
|
/* event loop */
|
||||||
|
u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits));
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
event = u8x8_GetMenuEvent(u8x8);
|
||||||
|
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
|
||||||
|
{
|
||||||
|
*value = local_value;
|
||||||
|
r = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
|
||||||
|
{
|
||||||
|
r = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP )
|
||||||
|
{
|
||||||
|
if ( local_value >= hi )
|
||||||
|
local_value = lo;
|
||||||
|
else
|
||||||
|
local_value++;
|
||||||
|
u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits));
|
||||||
|
}
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN )
|
||||||
|
{
|
||||||
|
if ( local_value <= lo )
|
||||||
|
local_value = hi;
|
||||||
|
else
|
||||||
|
local_value--;
|
||||||
|
u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u8x8_SetInverseFont(u8x8, 0);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
152
main/utilities/u8g2/src/u8x8_message.c
Normal file
152
main/utilities/u8g2/src/u8x8_message.c
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_message.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
uint8_t u8x8_draw_button_line(u8x8_t *u8x8, uint8_t y, uint8_t w, uint8_t cursor, const char *s)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t cnt;
|
||||||
|
uint8_t total;
|
||||||
|
uint8_t d;
|
||||||
|
uint8_t x;
|
||||||
|
cnt = u8x8_GetStringLineCnt(s);
|
||||||
|
|
||||||
|
/* calculate the width of the button */
|
||||||
|
total = 0;
|
||||||
|
for( i = 0; i < cnt; i++ )
|
||||||
|
{
|
||||||
|
total += u8x8_GetUTF8Len(u8x8, u8x8_GetStringLineStart(i, s));
|
||||||
|
}
|
||||||
|
total += (cnt-1); /* had one space between the buttons */
|
||||||
|
|
||||||
|
/* calculate the left offset */
|
||||||
|
d = 0;
|
||||||
|
if ( total < w )
|
||||||
|
{
|
||||||
|
d = w;
|
||||||
|
d -= total;
|
||||||
|
d /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draw the buttons */
|
||||||
|
x = d;
|
||||||
|
u8x8_SetInverseFont(u8x8, 0);
|
||||||
|
for( i = 0; i < cnt; i++ )
|
||||||
|
{
|
||||||
|
if ( i == cursor )
|
||||||
|
u8x8_SetInverseFont(u8x8, 1);
|
||||||
|
|
||||||
|
x+=u8x8_DrawUTF8(u8x8, x, y, u8x8_GetStringLineStart(i, s));
|
||||||
|
u8x8_SetInverseFont(u8x8, 0);
|
||||||
|
x+=u8x8_DrawUTF8(u8x8, x, y, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the number of buttons */
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
title1: Multiple lines,separated by '\n'
|
||||||
|
title2: A single line/string which is terminated by '\0' or '\n' . "title2" accepts the return value from u8x8_GetStringLineStart()
|
||||||
|
title3: Multiple lines,separated by '\n'
|
||||||
|
buttons: one more more buttons separated by '\n' and terminated with '\0'
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint8_t u8x8_UserInterfaceMessage(u8x8_t *u8x8, const char *title1, const char *title2, const char *title3, const char *buttons)
|
||||||
|
{
|
||||||
|
uint8_t height;
|
||||||
|
uint8_t y;
|
||||||
|
uint8_t cursor = 0;
|
||||||
|
uint8_t button_cnt;
|
||||||
|
uint8_t event;
|
||||||
|
|
||||||
|
u8x8_SetInverseFont(u8x8, 0);
|
||||||
|
|
||||||
|
/* calculate overall height of the message box */
|
||||||
|
height = 1; /* button line */
|
||||||
|
height += u8x8_GetStringLineCnt(title1);
|
||||||
|
if ( title2 != NULL )
|
||||||
|
height ++;
|
||||||
|
height += u8x8_GetStringLineCnt(title3);
|
||||||
|
|
||||||
|
/* calculate offset from top */
|
||||||
|
y = 0;
|
||||||
|
if ( height < u8x8_GetRows(u8x8) )
|
||||||
|
{
|
||||||
|
y = u8x8_GetRows(u8x8);
|
||||||
|
y -= height;
|
||||||
|
y /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draw message box */
|
||||||
|
|
||||||
|
u8x8_ClearDisplay(u8x8); /* required, because not everything is filled */
|
||||||
|
|
||||||
|
y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title1);
|
||||||
|
if ( title2 != NULL )
|
||||||
|
{
|
||||||
|
u8x8_DrawUTF8Line(u8x8, 0, y, u8x8_GetCols(u8x8), title2);
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title3);
|
||||||
|
|
||||||
|
button_cnt = u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
event = u8x8_GetMenuEvent(u8x8);
|
||||||
|
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
|
||||||
|
return cursor+1;
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
|
||||||
|
break;
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP )
|
||||||
|
{
|
||||||
|
cursor++;
|
||||||
|
if ( cursor >= button_cnt )
|
||||||
|
cursor = 0;
|
||||||
|
u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons);
|
||||||
|
}
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN )
|
||||||
|
{
|
||||||
|
if ( cursor == 0 )
|
||||||
|
cursor = button_cnt;
|
||||||
|
cursor--;
|
||||||
|
u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
173
main/utilities/u8g2/src/u8x8_selection_list.c
Normal file
173
main/utilities/u8g2/src/u8x8_selection_list.c
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_selection_list.c
|
||||||
|
|
||||||
|
selection list with scroll option
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
increase the cursor position
|
||||||
|
*/
|
||||||
|
void u8sl_Next(u8sl_t *u8sl)
|
||||||
|
{
|
||||||
|
u8sl->current_pos++;
|
||||||
|
if ( u8sl->current_pos >= u8sl->total )
|
||||||
|
{
|
||||||
|
u8sl->current_pos = 0;
|
||||||
|
u8sl->first_pos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( u8sl->first_pos + u8sl->visible <= u8sl->current_pos + 1 )
|
||||||
|
{
|
||||||
|
u8sl->first_pos = u8sl->current_pos - u8sl->visible + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8sl_Prev(u8sl_t *u8sl)
|
||||||
|
{
|
||||||
|
if ( u8sl->current_pos == 0 )
|
||||||
|
{
|
||||||
|
u8sl->current_pos = u8sl->total - 1;
|
||||||
|
u8sl->first_pos = 0;
|
||||||
|
if ( u8sl->total > u8sl->visible )
|
||||||
|
u8sl->first_pos = u8sl->total - u8sl->visible;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u8sl->current_pos--;
|
||||||
|
if ( u8sl->first_pos > u8sl->current_pos )
|
||||||
|
u8sl->first_pos = u8sl->current_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8x8_DrawSelectionList(u8x8_t *u8x8, u8sl_t *u8sl, u8x8_sl_cb sl_cb, const void *aux)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
for( i = 0; i < u8sl->visible; i++ )
|
||||||
|
{
|
||||||
|
sl_cb(u8x8, u8sl, i+u8sl->first_pos, aux);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* selection list with string line */
|
||||||
|
void u8x8_sl_string_line_cb(u8x8_t *u8x8, u8sl_t *u8sl, uint8_t idx, const void *aux)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
uint8_t row;
|
||||||
|
/* calculate offset from display upper border */
|
||||||
|
row = u8sl->y;
|
||||||
|
|
||||||
|
/* calculate target pos */
|
||||||
|
row += idx;
|
||||||
|
row -= u8sl->first_pos;
|
||||||
|
|
||||||
|
/* check whether this is the current cursor line */
|
||||||
|
if ( idx == u8sl->current_pos )
|
||||||
|
u8x8_SetInverseFont(u8x8, 1);
|
||||||
|
else
|
||||||
|
u8x8_SetInverseFont(u8x8, 0);
|
||||||
|
|
||||||
|
/* get the line from the array */
|
||||||
|
s = u8x8_GetStringLineStart(idx, (const char *)aux);
|
||||||
|
|
||||||
|
/* draw the line */
|
||||||
|
if ( s == NULL )
|
||||||
|
s = "";
|
||||||
|
u8x8_DrawUTF8Line(u8x8, u8sl->x, row, u8x8_GetCols(u8x8), s);
|
||||||
|
u8x8_SetInverseFont(u8x8, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n'
|
||||||
|
start_pos: default position for the cursor (starts with 1)
|
||||||
|
sl: string list (list of strings separated by \n)
|
||||||
|
returns 0 if user has pressed the home key
|
||||||
|
returns the selected line+1 if user has pressed the select key (e.g. 1 for the first line)
|
||||||
|
*/
|
||||||
|
uint8_t u8x8_UserInterfaceSelectionList(u8x8_t *u8x8, const char *title, uint8_t start_pos, const char *sl)
|
||||||
|
{
|
||||||
|
u8sl_t u8sl;
|
||||||
|
uint8_t event;
|
||||||
|
uint8_t title_lines;
|
||||||
|
|
||||||
|
if ( start_pos > 0 )
|
||||||
|
start_pos--;
|
||||||
|
|
||||||
|
u8sl.visible = u8x8_GetRows(u8x8);
|
||||||
|
u8sl.total = u8x8_GetStringLineCnt(sl);
|
||||||
|
u8sl.first_pos = 0;
|
||||||
|
u8sl.current_pos = start_pos;
|
||||||
|
u8sl.x = 0;
|
||||||
|
u8sl.y = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//u8x8_ClearDisplay(u8x8); /* not required because all is 100% filled */
|
||||||
|
u8x8_SetInverseFont(u8x8, 0);
|
||||||
|
|
||||||
|
if ( title != NULL )
|
||||||
|
{
|
||||||
|
title_lines = u8x8_DrawUTF8Lines(u8x8, u8sl.x, u8sl.y, u8x8_GetCols(u8x8), title);
|
||||||
|
u8sl.y+=title_lines;
|
||||||
|
u8sl.visible-=title_lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( u8sl.current_pos >= u8sl.total )
|
||||||
|
u8sl.current_pos = u8sl.total-1;
|
||||||
|
|
||||||
|
|
||||||
|
u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
event = u8x8_GetMenuEvent(u8x8);
|
||||||
|
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
|
||||||
|
return u8sl.current_pos+1;
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
|
||||||
|
return 0;
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN )
|
||||||
|
{
|
||||||
|
u8sl_Next(&u8sl);
|
||||||
|
u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl);
|
||||||
|
}
|
||||||
|
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP )
|
||||||
|
{
|
||||||
|
u8sl_Prev(&u8sl);
|
||||||
|
u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
147
main/utilities/u8g2/src/u8x8_setup.c
Normal file
147
main/utilities/u8g2/src/u8x8_setup.c
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_setup.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
/* universal dummy callback, which will be default for all callbacks */
|
||||||
|
uint8_t u8x8_dummy_cb(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
|
||||||
|
{
|
||||||
|
/* the dummy callback will not handle any message and will fail for all messages */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const u8x8_display_info_t u8x8_null_display_info =
|
||||||
|
{
|
||||||
|
/* chip_enable_level = */ 0,
|
||||||
|
/* chip_disable_level = */ 1,
|
||||||
|
|
||||||
|
/* post_chip_enable_wait_ns = */ 0,
|
||||||
|
/* pre_chip_disable_wait_ns = */ 0,
|
||||||
|
/* reset_pulse_width_ms = */ 0,
|
||||||
|
/* post_reset_wait_ms = */ 0,
|
||||||
|
/* sda_setup_time_ns = */ 0,
|
||||||
|
/* sck_pulse_width_ns = */ 0, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||||
|
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||||
|
/* spi_mode = */ 0, /* active high, rising edge */
|
||||||
|
/* i2c_bus_clock_100kHz = */ 4,
|
||||||
|
/* data_setup_time_ns = */ 0,
|
||||||
|
/* write_pulse_width_ns = */ 0,
|
||||||
|
/* tile_width = */ 1, /* 8x8 */
|
||||||
|
/* tile_hight = */ 1,
|
||||||
|
/* default_x_offset = */ 0,
|
||||||
|
/* flipmode_x_offset = */ 0,
|
||||||
|
/* pixel_width = */ 8,
|
||||||
|
/* pixel_height = */ 8
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* a special null device */
|
||||||
|
uint8_t u8x8_d_null_cb(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
|
||||||
|
{
|
||||||
|
switch(msg)
|
||||||
|
{
|
||||||
|
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||||
|
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_null_display_info);
|
||||||
|
break;
|
||||||
|
case U8X8_MSG_DISPLAY_INIT:
|
||||||
|
u8x8_d_helper_display_init(u8x8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* the null device callback will succeed for all messages */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Description:
|
||||||
|
Setup u8x8
|
||||||
|
Args:
|
||||||
|
u8x8 An empty u8x8 structure
|
||||||
|
*/
|
||||||
|
void u8x8_SetupDefaults(u8x8_t *u8x8)
|
||||||
|
{
|
||||||
|
u8x8->display_info = NULL;
|
||||||
|
u8x8->display_cb = u8x8_dummy_cb;
|
||||||
|
u8x8->cad_cb = u8x8_dummy_cb;
|
||||||
|
u8x8->byte_cb = u8x8_dummy_cb;
|
||||||
|
u8x8->gpio_and_delay_cb = u8x8_dummy_cb;
|
||||||
|
u8x8->is_font_inverse_mode = 0;
|
||||||
|
//u8x8->device_address = 0;
|
||||||
|
u8x8->utf8_state = 0; /* also reset by u8x8_utf8_init */
|
||||||
|
u8x8->bus_clock = 0; /* issue 769 */
|
||||||
|
u8x8->i2c_address = 255;
|
||||||
|
u8x8->debounce_default_pin_state = 255; /* assume all low active buttons */
|
||||||
|
|
||||||
|
#ifdef U8X8_USE_PINS
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
for( i = 0; i < U8X8_PIN_CNT; i++ )
|
||||||
|
u8x8->pins[i] = U8X8_PIN_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Description:
|
||||||
|
Setup u8x8 and assign the callback function. The dummy
|
||||||
|
callback "u8x8_dummy_cb" can be used, if no callback is required.
|
||||||
|
This setup will not communicate with the display itself.
|
||||||
|
Use u8x8_InitDisplay() to send the startup code to the Display.
|
||||||
|
Args:
|
||||||
|
u8x8 An empty u8x8 structure
|
||||||
|
display_cb Display/controller specific callback function
|
||||||
|
cad_cb Display controller specific communication callback function
|
||||||
|
byte_cb Display controller/communication specific callback funtion
|
||||||
|
gpio_and_delay_cb Environment specific callback function
|
||||||
|
|
||||||
|
*/
|
||||||
|
void u8x8_Setup(u8x8_t *u8x8, u8x8_msg_cb display_cb, u8x8_msg_cb cad_cb, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||||
|
{
|
||||||
|
/* setup defaults and reset pins to U8X8_PIN_NONE */
|
||||||
|
u8x8_SetupDefaults(u8x8);
|
||||||
|
|
||||||
|
/* setup specific callbacks */
|
||||||
|
u8x8->display_cb = display_cb;
|
||||||
|
u8x8->cad_cb = cad_cb;
|
||||||
|
u8x8->byte_cb = byte_cb;
|
||||||
|
u8x8->gpio_and_delay_cb = gpio_and_delay_cb;
|
||||||
|
|
||||||
|
/* setup display info */
|
||||||
|
u8x8_SetupMemory(u8x8);
|
||||||
|
}
|
||||||
|
|
||||||
170
main/utilities/u8g2/src/u8x8_string.c
Normal file
170
main/utilities/u8g2/src/u8x8_string.c
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_string.c
|
||||||
|
|
||||||
|
string line procedures
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
uint8_t u8x8_GetStringLineCnt(const char *str)
|
||||||
|
{
|
||||||
|
char e;
|
||||||
|
uint8_t line_cnt = 1;
|
||||||
|
if ( str == NULL )
|
||||||
|
return 0;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
e = *str;
|
||||||
|
if ( e == '\0' )
|
||||||
|
break;
|
||||||
|
str++;
|
||||||
|
if ( e == '\n' )
|
||||||
|
line_cnt++;
|
||||||
|
}
|
||||||
|
return line_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Assumes strings, separated by '\n' in "str".
|
||||||
|
Returns the string at index "line_idx". First strng has line_idx = 0
|
||||||
|
Example:
|
||||||
|
Returns "xyz" for line_idx = 1 with str = "abc\nxyz"
|
||||||
|
Support both UTF8 and normal strings.
|
||||||
|
*/
|
||||||
|
const char *u8x8_GetStringLineStart(uint8_t line_idx, const char *str )
|
||||||
|
{
|
||||||
|
char e;
|
||||||
|
uint8_t line_cnt = 1;
|
||||||
|
|
||||||
|
if ( line_idx == 0 )
|
||||||
|
return str;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
e = *str;
|
||||||
|
if ( e == '\0' )
|
||||||
|
break;
|
||||||
|
str++;
|
||||||
|
if ( e == '\n' )
|
||||||
|
{
|
||||||
|
if ( line_cnt == line_idx )
|
||||||
|
return str;
|
||||||
|
line_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL; /* line not found */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy until first '\n' or '\0' in str */
|
||||||
|
/* Important: There is no string overflow check, ensure */
|
||||||
|
/* that the destination buffer is large enough */
|
||||||
|
void u8x8_CopyStringLine(char *dest, uint8_t line_idx, const char *str)
|
||||||
|
{
|
||||||
|
if ( dest == NULL )
|
||||||
|
return;
|
||||||
|
str = u8x8_GetStringLineStart( line_idx, str );
|
||||||
|
if ( str != NULL )
|
||||||
|
{
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if ( *str == '\n' || *str == '\0' )
|
||||||
|
break;
|
||||||
|
*dest = *str;
|
||||||
|
dest++;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*dest = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Draw a string
|
||||||
|
Extend the string to size "w"
|
||||||
|
Center the string within "w"
|
||||||
|
return the size of the string
|
||||||
|
|
||||||
|
*/
|
||||||
|
uint8_t u8x8_DrawUTF8Line(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s)
|
||||||
|
{
|
||||||
|
uint8_t d, lw;
|
||||||
|
uint8_t cx, dx;
|
||||||
|
|
||||||
|
d = 0;
|
||||||
|
|
||||||
|
lw = u8x8_GetUTF8Len(u8x8, s);
|
||||||
|
if ( lw < w )
|
||||||
|
{
|
||||||
|
d = w;
|
||||||
|
d -=lw;
|
||||||
|
d /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
cx = x;
|
||||||
|
dx = cx + d;
|
||||||
|
while( cx < dx )
|
||||||
|
{
|
||||||
|
u8x8_DrawUTF8(u8x8, cx, y, " ");
|
||||||
|
cx++;
|
||||||
|
}
|
||||||
|
cx += u8x8_DrawUTF8(u8x8, cx, y, s);
|
||||||
|
dx = x + w;
|
||||||
|
while( cx < dx )
|
||||||
|
{
|
||||||
|
u8x8_DrawUTF8(u8x8, cx, y, " ");
|
||||||
|
cx++;
|
||||||
|
}
|
||||||
|
cx -= x;
|
||||||
|
return cx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
draw several lines at position x,y.
|
||||||
|
lines are stored in s and must be separated with '\n'.
|
||||||
|
lines can be centered with respect to "w"
|
||||||
|
if s == NULL nothing is drawn and 0 is returned
|
||||||
|
returns the number of lines in s
|
||||||
|
*/
|
||||||
|
uint8_t u8x8_DrawUTF8Lines(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t cnt;
|
||||||
|
cnt = u8x8_GetStringLineCnt(s);
|
||||||
|
for( i = 0; i < cnt; i++ )
|
||||||
|
{
|
||||||
|
u8x8_DrawUTF8Line(u8x8, x, y, w, u8x8_GetStringLineStart(i, s));
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
77
main/utilities/u8g2/src/u8x8_u16toa.c
Normal file
77
main/utilities/u8g2/src/u8x8_u16toa.c
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_u16toa.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
const char *u8x8_u16toap(char * dest, uint16_t v)
|
||||||
|
{
|
||||||
|
uint8_t pos;
|
||||||
|
uint8_t d;
|
||||||
|
uint16_t c;
|
||||||
|
c = 10000;
|
||||||
|
for( pos = 0; pos < 5; pos++ )
|
||||||
|
{
|
||||||
|
d = '0';
|
||||||
|
while( v >= c )
|
||||||
|
{
|
||||||
|
v -= c;
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
dest[pos] = d;
|
||||||
|
c /= 10;
|
||||||
|
}
|
||||||
|
dest[5] = '\0';
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* v = value, d = number of digits */
|
||||||
|
const char *u8x8_u16toa(uint16_t v, uint8_t d)
|
||||||
|
{
|
||||||
|
static char buf[6];
|
||||||
|
d = 5-d;
|
||||||
|
return u8x8_u16toap(buf, v) + d;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *u8x8_utoa(uint16_t v)
|
||||||
|
{
|
||||||
|
const char *s = u8x8_u16toa(v, 5);
|
||||||
|
while( *s == '0' )
|
||||||
|
s++;
|
||||||
|
if ( *s == '\0' )
|
||||||
|
s--;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
93
main/utilities/u8g2/src/u8x8_u8toa.c
Normal file
93
main/utilities/u8g2/src/u8x8_u8toa.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
u8x8_u8toa.c
|
||||||
|
|
||||||
|
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||||
|
|
||||||
|
Copyright (c) 2016, olikraus@gmail.com
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "u8x8.h"
|
||||||
|
|
||||||
|
static const unsigned char u8x8_u8toa_tab[3] = { 100, 10, 1 } ;
|
||||||
|
const char *u8x8_u8toap(char * dest, uint8_t v)
|
||||||
|
{
|
||||||
|
uint8_t pos;
|
||||||
|
uint8_t d;
|
||||||
|
uint8_t c;
|
||||||
|
for( pos = 0; pos < 3; pos++ )
|
||||||
|
{
|
||||||
|
d = '0';
|
||||||
|
c = *(u8x8_u8toa_tab+pos);
|
||||||
|
while( v >= c )
|
||||||
|
{
|
||||||
|
v -= c;
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
dest[pos] = d;
|
||||||
|
}
|
||||||
|
dest[3] = '\0';
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* v = value, d = number of digits */
|
||||||
|
const char *u8x8_u8toa(uint8_t v, uint8_t d)
|
||||||
|
{
|
||||||
|
static char buf[4];
|
||||||
|
d = 3-d;
|
||||||
|
return u8x8_u8toap(buf, v) + d;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *u8x8_s8toa(int8_t v, uint8_t d)
|
||||||
|
{
|
||||||
|
static char buf[5];
|
||||||
|
uint16_t u = v;
|
||||||
|
buf[0] = '+';
|
||||||
|
if ( v < 0 )
|
||||||
|
{
|
||||||
|
buf[0] = '-';
|
||||||
|
u = -v;
|
||||||
|
}
|
||||||
|
u8x8_u8toap(buf+1, (uint8_t)u);
|
||||||
|
if ( d == 1 )
|
||||||
|
{
|
||||||
|
buf[1] = buf[3];
|
||||||
|
buf[2] = '\0';
|
||||||
|
}
|
||||||
|
else if ( d == 2 )
|
||||||
|
{
|
||||||
|
buf[1] = buf[2];
|
||||||
|
buf[2] = buf[3];
|
||||||
|
buf[3] = '\0';
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user