mirror of
https://github.com/Lurkars/esp-ena.git
synced 2026-05-08 20:10:37 +02:00
added dependable build for interface choice in menuconfig
This commit is contained in:
@@ -1,6 +1,28 @@
|
||||
set(src_list "display.c" "display-gfx.c")
|
||||
set(include_list ".")
|
||||
|
||||
if(CONFIG_ENA_INTERFACE_DISPLAY_SSD1306)
|
||||
list(APPEND src_list "custom-ssd1306/ssd1306.c")
|
||||
list(APPEND include_list "custom-ssd1306")
|
||||
elseif(CONFIG_ENA_INTERFACE_M5STICKC)
|
||||
list(APPEND src_list "m5-st7735s/st7735s.c" "m5-axp192/axp192.c")
|
||||
list(APPEND include_list "m5-st7735s" "m5-axp192")
|
||||
elseif(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
|
||||
list(APPEND src_list "m5-st7789/st7789.c" "m5-axp192/axp192.c")
|
||||
list(APPEND include_list "m5-st7789" "m5-axp192")
|
||||
elseif(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
|
||||
list(APPEND src_list "ttgo-st7735/st7735.c")
|
||||
list(APPEND include_list "ttgo-st7735")
|
||||
else()
|
||||
list(APPEND src_list "dummy.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"display.c"
|
||||
"display-gfx.c"
|
||||
INCLUDE_DIRS "."
|
||||
${src_list}
|
||||
INCLUDE_DIRS
|
||||
${include_list}
|
||||
PRIV_REQUIRES
|
||||
"i2c-main"
|
||||
"spi_flash"
|
||||
)
|
||||
@@ -0,0 +1,247 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <string.h>
|
||||
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "i2c-main.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "display-gfx.h"
|
||||
#include "ssd1306.h"
|
||||
|
||||
void display_start(void)
|
||||
{
|
||||
if (!i2c_is_initialized())
|
||||
{
|
||||
i2c_main_init();
|
||||
}
|
||||
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
|
||||
i2c_master_start(cmd);
|
||||
// Begin the I2C comm with SSD1306's address (SLA+Write)
|
||||
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
// Tell the SSD1306 that a command stream is incoming
|
||||
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
|
||||
// Turn the Display OFF
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_OFF, true);
|
||||
// Set mux ration tp select max number of rows - 64
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_MULTIPLEX_RATIO, true);
|
||||
i2c_master_write_byte(cmd, 0x3F, true);
|
||||
// Set the display offset to 0
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_OFFSET, true);
|
||||
i2c_master_write_byte(cmd, 0x00, true);
|
||||
// Display start line to 0
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_START_LINE, true);
|
||||
// Mirror the x-axis. In case you set it up such that the pins are north.
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_SEGMENT_HIGH, true);
|
||||
// Mirror the y-axis. In case you set it up such that the pins are north.
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_SCAN_DIRECTION_REMAPPED, true);
|
||||
// Default - alternate COM pin map
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_COM_PINS, true);
|
||||
i2c_master_write_byte(cmd, 0x12, true);
|
||||
// set contrast
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_CONTRAST, true);
|
||||
i2c_master_write_byte(cmd, 0xFF, true);
|
||||
// Set display to enable rendering from GDDRAM (Graphic Display Data RAM)
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_RAM, true);
|
||||
// Normal mode!
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_NORMAL, true);
|
||||
// Default oscillator clock
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_CLOCK, true);
|
||||
i2c_master_write_byte(cmd, 0x80, true);
|
||||
// Enable the charge pump
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_CHARGE_PUMP, true);
|
||||
i2c_master_write_byte(cmd, 0x14, true);
|
||||
// Set precharge cycles to high cap type
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_PRE_CHARGE_PERIOD, true);
|
||||
i2c_master_write_byte(cmd, 0x22, true);
|
||||
// Set the V_COMH deselect volatage to max
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_VCOMH, true);
|
||||
i2c_master_write_byte(cmd, 0x30, true);
|
||||
// Horizonatal addressing mode to page addressing
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_MEMORY_MODE, true);
|
||||
i2c_master_write_byte(cmd, 0x02, true);
|
||||
//i2c_master_write_byte(cmd, 0x00, true);
|
||||
// i2c_master_write_byte(cmd, 0x10, true);
|
||||
// i2c_master_write_byte(cmd, SSD1306_CMD_SCROLL_STOP, true);
|
||||
// Turn the Display ON
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_ON, true);
|
||||
i2c_master_stop(cmd);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
void display_init_data(void)
|
||||
{
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
// Begin the I2C comm with SSD1306's address (SLA+Write)
|
||||
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
// Tell the SSD1306 that a command stream is incoming
|
||||
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
|
||||
|
||||
// set column start + end
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_LOW, true);
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_HIGH, true);
|
||||
|
||||
// set page
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_PAGE, true);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
void display_clear_line(uint8_t line, bool invert)
|
||||
{
|
||||
i2c_cmd_handle_t cmd;
|
||||
uint8_t *zeros = calloc(SSD1306_COLUMNS, sizeof(uint8_t));
|
||||
// set line
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
|
||||
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_LOW, true);
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_HIGH, true);
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_PAGE | line, true);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
|
||||
// fill line with zeros
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, SSD1306_CONTROL_DATA_STREAM, true);
|
||||
i2c_master_write(cmd, zeros, SSD1306_COLUMNS, true);
|
||||
i2c_master_stop(cmd);
|
||||
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
|
||||
free(zeros);
|
||||
}
|
||||
|
||||
void display_clear(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < SSD1306_PAGES; i++)
|
||||
{
|
||||
display_clear_line(i, false);
|
||||
}
|
||||
}
|
||||
|
||||
void display_on(bool on)
|
||||
{
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
|
||||
i2c_master_start(cmd);
|
||||
// Begin the I2C comm with SSD1306's address (SLA+Write)
|
||||
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
// Tell the SSD1306 that a command stream is incoming
|
||||
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
|
||||
if (on)
|
||||
{
|
||||
// Turn the Display ON
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_ON, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Turn the Display OFF
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_OFF, true);
|
||||
}
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert)
|
||||
{
|
||||
|
||||
uint8_t column = offset;
|
||||
if (column > SSD1306_COLUMNS)
|
||||
{
|
||||
column = 0;
|
||||
}
|
||||
size_t columns = length;
|
||||
if (columns > (SSD1306_COLUMNS - column))
|
||||
{
|
||||
columns = (SSD1306_COLUMNS - column);
|
||||
}
|
||||
|
||||
display_init_data();
|
||||
i2c_cmd_handle_t cmd;
|
||||
|
||||
// set line
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
|
||||
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_LOW | (column & 0XF), true);
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_HIGH | (column >> 4), true);
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_PAGE | line, true);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
|
||||
if (invert)
|
||||
{
|
||||
for (uint8_t i = 0; i < columns; i++)
|
||||
{
|
||||
data[i] = ~data[i];
|
||||
}
|
||||
}
|
||||
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, SSD1306_CONTROL_DATA_STREAM, true);
|
||||
|
||||
i2c_master_write(cmd, data, columns, true);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
void display_flipped(bool flipped)
|
||||
{
|
||||
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
// Begin the I2C comm with SSD1306's address (SLA+Write)
|
||||
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
// Tell the SSD1306 that a command stream is incoming
|
||||
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_SEGMENT_HIGH, true);
|
||||
|
||||
if (flipped)
|
||||
{
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_SCAN_DIRECTION_NORMAL, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_SCAN_DIRECTION_REMAPPED, true);
|
||||
}
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief I2C driver for SSD1306 display
|
||||
*
|
||||
*/
|
||||
#ifndef _ssd1306_H_
|
||||
#define _ssd1306_H_
|
||||
|
||||
#include "esp_system.h"
|
||||
|
||||
#define SSD1306_ADDRESS (0x3C)
|
||||
#define SSD1306_COLUMNS (128)
|
||||
#define SSD1306_PAGES (8)
|
||||
|
||||
// Write mode for I2C https://robotcantalk.blogspot.com/2015/03/interfacing-arduino-with-ssd1306-driven.html
|
||||
#define SSD1306_CONTROL_CMD_BYTE (0x80)
|
||||
#define SSD1306_CONTROL_CMD_STREAM (0x00)
|
||||
#define SSD1306_CONTROL_DATA_BYTE (0xC0)
|
||||
#define SSD1306_CONTROL_DATA_STREAM (0x40)
|
||||
|
||||
// 1. Fundamental Command Table
|
||||
#define SSD1306_CMD_CONTRAST (0x81)
|
||||
#define SSD1306_CMD_RAM (0xA4)
|
||||
#define SSD1306_CMD_ALL_ON (0xA5)
|
||||
#define SSD1306_CMD_NORMAL (0xA6)
|
||||
#define SSD1306_CMD_INVERSE (0xA7)
|
||||
#define SSD1306_CMD_OFF (0xAE)
|
||||
#define SSD1306_CMD_ON (0xAF)
|
||||
|
||||
// 2. Scrolling Command Table
|
||||
#define SSD1306_CMD_SCROLL_HORI_RIGHT (0x26)
|
||||
#define SSD1306_CMD_SCROLL_HORI_LEFT (0x27)
|
||||
#define SSD1306_CMD_SCROLL_VERT_RIGHT (0x29)
|
||||
#define SSD1306_CMD_SCROLL_VERT_LEFT (0x2A)
|
||||
#define SSD1306_CMD_SCROLL_STOP (0x2E)
|
||||
#define SSD1306_CMD_SCROLL_START (0x2F)
|
||||
#define SSD1306_CMD_SCROLL_VERT_AREA (0xA3)
|
||||
|
||||
// 3. Addressing Setting Command Table
|
||||
#define SSD1306_CMD_COLUMN_LOW (0x00)
|
||||
#define SSD1306_CMD_COLUMN_HIGH (0x10)
|
||||
#define SSD1306_CMD_MEMORY_MODE (0x20)
|
||||
#define SSD1306_CMD_COLUMN_ADDRESS (0x21)
|
||||
#define SSD1306_CMD_PAGE_ADDRESS (0x22)
|
||||
#define SSD1306_CMD_PAGE (0xB0)
|
||||
|
||||
// 4. Hardware Configuration (Panel resolution & layout related) Command Table
|
||||
#define SSD1306_CMD_START_LINE (0x40)
|
||||
#define SSD1306_CMD_SEGMENT_LOW (0xA0)
|
||||
#define SSD1306_CMD_SEGMENT_HIGH (0xA1)
|
||||
#define SSD1306_CMD_MULTIPLEX_RATIO (0xA8)
|
||||
#define SSD1306_CMD_SCAN_DIRECTION_NORMAL (0xC0)
|
||||
#define SSD1306_CMD_SCAN_DIRECTION_REMAPPED (0xC8)
|
||||
#define SSD1306_CMD_OFFSET (0xD3)
|
||||
#define SSD1306_CMD_COM_PINS (0xDA)
|
||||
|
||||
// 5. Timing & Driving Scheme Setting Command Table
|
||||
#define SSD1306_CMD_CLOCK (0xD5)
|
||||
#define SSD1306_CMD_PRE_CHARGE_PERIOD (0xD9)
|
||||
#define SSD1306_CMD_VCOMH (0xDB)
|
||||
#define SSD1306_CMD_NOP (0xE3)
|
||||
|
||||
// 1. Charge Pump Command Table
|
||||
#define SSD1306_CMD_CHARGE_PUMP (0x8D)
|
||||
|
||||
#endif
|
||||
@@ -34,6 +34,63 @@
|
||||
#define CYAN 0x07FF
|
||||
#define PURPLE 0xF81F
|
||||
|
||||
/**
|
||||
* @brief initalize display
|
||||
*
|
||||
* MUST BE DEFINED DEVICE SPECIFIC
|
||||
*
|
||||
*/
|
||||
void display_start(void);
|
||||
|
||||
/**
|
||||
* @brief clear the display
|
||||
*
|
||||
* MUST BE DEFINED DEVICE SPECIFIC
|
||||
*
|
||||
* @param[in] line the line to clear
|
||||
* @param[in] invert if true, image is inverted
|
||||
*/
|
||||
void display_clear_line(uint8_t line, bool invert);
|
||||
|
||||
/**
|
||||
* @brief clear the display
|
||||
*
|
||||
* MUST BE DEFINED DEVICE SPECIFIC
|
||||
*
|
||||
*/
|
||||
void display_clear(void);
|
||||
|
||||
/**
|
||||
* @brief set display on or off
|
||||
*
|
||||
* MUST BE DEFINED DEVICE SPECIFIC
|
||||
*
|
||||
* @param[in] on true if display on, false if display off
|
||||
*/
|
||||
void display_on(bool on);
|
||||
|
||||
/**
|
||||
* @brief set display flipped or not
|
||||
*
|
||||
* MUST BE DEFINED DEVICE SPECIFIC
|
||||
*
|
||||
* @param[in] on true display is flipped
|
||||
*/
|
||||
void display_flipped(bool flipped);
|
||||
|
||||
/**
|
||||
* @brief write raw bytes to display line at starting column
|
||||
*
|
||||
* MUST BE DEFINED DEVICE SPECIFIC
|
||||
*
|
||||
* @param[in] data bytes to display
|
||||
* @param[in] length length of data
|
||||
* @param[in] line the line to write to
|
||||
* @param[in] offset number of offset chars to start
|
||||
* @param[in] invert if true, image is inverted
|
||||
*/
|
||||
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -44,55 +101,11 @@ void display_utf8_to_ascii(char *input, char *output);
|
||||
*/
|
||||
uint8_t *display_text_to_data(char *text, size_t text_length, size_t *length);
|
||||
|
||||
/**
|
||||
* @brief initalize display
|
||||
*/
|
||||
void display_start(void);
|
||||
|
||||
/**
|
||||
* @brief clear the display
|
||||
*
|
||||
* @param[in] line the line to clear
|
||||
* @param[in] invert if true, image is inverted
|
||||
*/
|
||||
void display_clear_line(uint8_t line, bool invert);
|
||||
|
||||
/**
|
||||
* @brief clear the display
|
||||
*
|
||||
*/
|
||||
void display_clear(void);
|
||||
|
||||
/**
|
||||
* @brief set display on or off
|
||||
*
|
||||
* @param[in] on true if display on, false if display off
|
||||
*/
|
||||
void display_on(bool on);
|
||||
|
||||
/**
|
||||
* @brief set display flipped or not
|
||||
*
|
||||
* @param[in] on true display is flipped
|
||||
*/
|
||||
void display_flipped(bool flipped);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
uint8_t *display_text_to_data(char *text, size_t text_length, size_t *length);
|
||||
|
||||
/**
|
||||
* @brief write raw bytes to display line at starting column
|
||||
*
|
||||
* @param[in] data bytes to display
|
||||
* @param[in] length length of data
|
||||
* @param[in] line the line to write to
|
||||
* @param[in] offset number of offset chars to start
|
||||
* @param[in] invert if true, image is inverted
|
||||
*/
|
||||
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert);
|
||||
|
||||
/**
|
||||
* @brief write chars to display
|
||||
*
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <string.h>
|
||||
#include "display.h"
|
||||
|
||||
void display_start(void)
|
||||
{
|
||||
}
|
||||
|
||||
void display_clear_line(uint8_t line, bool invert)
|
||||
{
|
||||
}
|
||||
|
||||
void display_clear(void)
|
||||
{
|
||||
}
|
||||
|
||||
void display_on(bool on)
|
||||
{
|
||||
}
|
||||
|
||||
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert)
|
||||
{
|
||||
}
|
||||
|
||||
void display_flipped(bool flipped)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,483 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "i2c-main.h"
|
||||
|
||||
#include "axp192.h"
|
||||
|
||||
void axp192_write_byte(uint8_t addr, uint8_t data)
|
||||
{
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
|
||||
i2c_master_start(cmd);
|
||||
// Begin the I2C comm with AXP192_ADDRESS's address (SLA+Write)
|
||||
i2c_master_write_byte(cmd, (AXP192_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
|
||||
i2c_master_write_byte(cmd, addr, true);
|
||||
i2c_master_write_byte(cmd, data, true);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
void axp192_read_buff(uint8_t addr, uint8_t size, uint8_t *buff)
|
||||
{
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
|
||||
// Send register address
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (AXP192_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, addr, true);
|
||||
|
||||
// Receive data
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (AXP192_ADDRESS << 1) | I2C_MASTER_READ, true);
|
||||
i2c_master_read(cmd, buff, size, I2C_MASTER_LAST_NACK);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
uint8_t axp192_read_8bit(uint8_t addr)
|
||||
{
|
||||
uint8_t data;
|
||||
axp192_read_buff(addr, 1, &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t axp192_read_12bit(uint8_t addr)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(addr, 2, buf);
|
||||
data = ((buf[0] << 4) + buf[1]); //
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t axp192_read_13bit(uint8_t addr)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(addr, 2, buf);
|
||||
data = ((buf[0] << 5) + buf[1]); //
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t axp192_read_16bit(uint8_t addr)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(addr, 2, buf);
|
||||
data = ((buf[0] << 8) + buf[1]);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint32_t axp192_read_24bit(uint8_t addr)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
uint8_t buf[3];
|
||||
axp192_read_buff(addr, 3, buf);
|
||||
data = ((buf[0] << 16) + (buf[1] << 8) + buf[2]);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint32_t axp192_read_32bit(uint8_t addr)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
uint8_t buf[4];
|
||||
axp192_read_buff(addr, 4, buf);
|
||||
data = ((buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]);
|
||||
return data;
|
||||
}
|
||||
|
||||
void axp192_screen_breath(uint8_t brightness)
|
||||
{
|
||||
if (brightness > 12)
|
||||
{
|
||||
brightness = 12;
|
||||
}
|
||||
uint8_t buf = axp192_read_8bit(0x28);
|
||||
axp192_write_byte(0x28, ((buf & 0x0f) | (brightness << 4)));
|
||||
}
|
||||
|
||||
void axp192_start(void)
|
||||
{
|
||||
if (!i2c_is_initialized())
|
||||
{
|
||||
i2c_main_init();
|
||||
}
|
||||
|
||||
// Set LDO2 & LDO3(ST7789_LED & TFT) 3.0V
|
||||
axp192_write_byte(0x28, 0xcc);
|
||||
|
||||
// Set ADC sample rate to 200hz
|
||||
axp192_write_byte(0x84, 0xF2);
|
||||
|
||||
// Set ADC to All Enable
|
||||
axp192_write_byte(0x82, 0xff);
|
||||
|
||||
// Bat charge voltage to 4.2, Current 100MA
|
||||
axp192_write_byte(0x33, 0xc0);
|
||||
|
||||
// Enable Bat,ACIN,VBUS,APS adc
|
||||
axp192_write_byte(0x82, 0xff);
|
||||
|
||||
// Enable Ext, LDO2, LDO3, DCDC1
|
||||
axp192_write_byte(0x12, axp192_read_8bit(0x12) | 0x4D);
|
||||
|
||||
// 128ms power on, 4s power off
|
||||
axp192_write_byte(0x36, 0x0C);
|
||||
|
||||
// Set RTC voltage to 3.3V
|
||||
axp192_write_byte(0x91, 0xF0);
|
||||
|
||||
// Set GPIO0 to LDO
|
||||
axp192_write_byte(0x90, 0x02);
|
||||
|
||||
// Disable vbus hold limit
|
||||
axp192_write_byte(0x30, 0x80);
|
||||
|
||||
// Set temperature protection
|
||||
axp192_write_byte(0x39, 0xfc);
|
||||
|
||||
// Enable RTC BAT charge
|
||||
axp192_write_byte(0x35, 0xa2);
|
||||
|
||||
// Enable bat detection
|
||||
axp192_write_byte(0x32, 0x46);
|
||||
}
|
||||
|
||||
bool axp192_get_bat_state()
|
||||
{
|
||||
if (axp192_read_8bit(0x01) | 0x20)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
//---------coulombcounter_from_here---------
|
||||
//enable: void EnableCoulombcounter(void);
|
||||
//disable: void DisableCOulombcounter(void);
|
||||
//stop: void StopCoulombcounter(void);
|
||||
//clear: void ClearCoulombcounter(void);
|
||||
//get charge data: uint32_t GetCoulombchargedata(void);
|
||||
//get discharge data: uint32_t GetCoulombdischargedata(void);
|
||||
//get coulomb val affter calculation: float GetCoulombdata(void);
|
||||
//------------------------------------------
|
||||
void axp192_enable_coulombcounter(void)
|
||||
{
|
||||
axp192_write_byte(0xB8, 0x80);
|
||||
}
|
||||
|
||||
void axp192_disable_coulombcounter(void)
|
||||
{
|
||||
axp192_write_byte(0xB8, 0x00);
|
||||
}
|
||||
|
||||
void axp192_stop_coulombcounter(void)
|
||||
{
|
||||
axp192_write_byte(0xB8, 0xC0);
|
||||
}
|
||||
|
||||
void axp192_clear_coulombcounter(void)
|
||||
{
|
||||
axp192_write_byte(0xB8, 0xA0);
|
||||
}
|
||||
|
||||
uint32_t axp192_get_coulombcharge_data(void)
|
||||
{
|
||||
return axp192_read_32bit(0xB0);
|
||||
}
|
||||
|
||||
uint32_t axp192_get_coulombdischarge_data(void)
|
||||
{
|
||||
return axp192_read_32bit(0xB4);
|
||||
}
|
||||
|
||||
float axp192_get_coulomb_data(void)
|
||||
{
|
||||
|
||||
uint32_t coin = 0;
|
||||
uint32_t coout = 0;
|
||||
|
||||
coin = axp192_get_coulombcharge_data();
|
||||
coout = axp192_get_coulombdischarge_data();
|
||||
|
||||
//c = 65536 * current_LSB * (coin - coout) / 3600 / ADC rate
|
||||
//Adc rate can be read from 84H ,change this variable if you change the ADC reate
|
||||
float ccc = 65536 * 0.5 * (coin - coout) / 3600.0 / 25.0;
|
||||
return ccc;
|
||||
}
|
||||
//----------coulomb_end_at_here----------
|
||||
|
||||
uint16_t axp192_get_Vbatdata(void)
|
||||
{
|
||||
|
||||
uint16_t vbat = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x78, 2, buf);
|
||||
vbat = ((buf[0] << 4) + buf[1]); // V
|
||||
return vbat;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Vindata(void)
|
||||
{
|
||||
uint16_t vin = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x56, 2, buf);
|
||||
vin = ((buf[0] << 4) + buf[1]); // V
|
||||
return vin;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Iindata(void)
|
||||
{
|
||||
uint16_t iin = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x58, 2, buf);
|
||||
iin = ((buf[0] << 4) + buf[1]);
|
||||
return iin;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Vusbindata(void)
|
||||
{
|
||||
uint16_t vin = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x5a, 2, buf);
|
||||
vin = ((buf[0] << 4) + buf[1]); // V
|
||||
return vin;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Iusbindata(void)
|
||||
{
|
||||
uint16_t iin = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x5C, 2, buf);
|
||||
iin = ((buf[0] << 4) + buf[1]);
|
||||
return iin;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Ichargedata(void)
|
||||
{
|
||||
|
||||
uint16_t icharge = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x7A, 2, buf);
|
||||
icharge = (buf[0] << 5) + buf[1];
|
||||
return icharge;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Idischargedata(void)
|
||||
{
|
||||
uint16_t idischarge = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x7C, 2, buf);
|
||||
idischarge = (buf[0] << 5) + buf[1];
|
||||
return idischarge;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Tempdata(void)
|
||||
{
|
||||
uint16_t temp = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x5e, 2, buf);
|
||||
temp = ((buf[0] << 4) + buf[1]);
|
||||
return temp;
|
||||
}
|
||||
|
||||
uint32_t axp192_get_Powerbatdata(void)
|
||||
{
|
||||
uint32_t power = 0;
|
||||
uint8_t buf[3];
|
||||
axp192_read_buff(0x70, 2, buf);
|
||||
power = (buf[0] << 16) + (buf[1] << 8) + buf[2];
|
||||
return power;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Vapsdata(void)
|
||||
{
|
||||
uint16_t vaps = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x7e, 2, buf);
|
||||
vaps = ((buf[0] << 4) + buf[1]);
|
||||
return vaps;
|
||||
}
|
||||
|
||||
void axp192_set_sleep(void)
|
||||
{
|
||||
uint8_t buf = axp192_read_8bit(0x31);
|
||||
buf = (1 << 3) | buf;
|
||||
axp192_write_byte(0x31, buf);
|
||||
axp192_write_byte(0x90, 0x00);
|
||||
axp192_write_byte(0x12, 0x09);
|
||||
axp192_write_byte(0x12, 0x00);
|
||||
}
|
||||
|
||||
uint8_t axp192_get_warning_leve(void)
|
||||
{
|
||||
uint8_t buf = axp192_read_8bit(0x47);
|
||||
return (buf & 0x01);
|
||||
}
|
||||
|
||||
// -- sleep
|
||||
void axp192_deep_sleep(uint64_t time_in_us)
|
||||
{
|
||||
axp192_set_sleep();
|
||||
|
||||
if (time_in_us > 0)
|
||||
{
|
||||
esp_sleep_enable_timer_wakeup(time_in_us);
|
||||
}
|
||||
else
|
||||
{
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
|
||||
}
|
||||
(time_in_us == 0) ? esp_deep_sleep_start() : esp_deep_sleep(time_in_us);
|
||||
}
|
||||
|
||||
void axp192_light_sleep(uint64_t time_in_us)
|
||||
{
|
||||
axp192_set_sleep();
|
||||
|
||||
if (time_in_us > 0)
|
||||
{
|
||||
esp_sleep_enable_timer_wakeup(time_in_us);
|
||||
}
|
||||
else
|
||||
{
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
|
||||
}
|
||||
esp_light_sleep_start();
|
||||
}
|
||||
|
||||
// 0 not press, 0x01 long press, 0x02 press
|
||||
uint8_t axp192_get_btn_press()
|
||||
{
|
||||
uint8_t state = axp192_read_8bit(0x46);
|
||||
if (state)
|
||||
{
|
||||
axp192_write_byte(0x46, 0x03);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
uint8_t axp192_get_warning_level(void)
|
||||
{
|
||||
return axp192_read_8bit(0x47) & 0x01;
|
||||
}
|
||||
|
||||
float axp192_get_bat_voltage()
|
||||
{
|
||||
float ADCLSB = 1.1 / 1000.0;
|
||||
uint16_t Redata = axp192_read_12bit(0x78);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_bat_current()
|
||||
{
|
||||
float ADCLSB = 0.5;
|
||||
uint16_t CurrentIn = axp192_read_13bit(0x7A);
|
||||
uint16_t CurrentOut = axp192_read_13bit(0x7C);
|
||||
return (CurrentIn - CurrentOut) * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_vin_voltage()
|
||||
{
|
||||
float ADCLSB = 1.7 / 1000.0;
|
||||
uint16_t Redata = axp192_read_12bit(0x56);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_vin_current()
|
||||
{
|
||||
float ADCLSB = 0.625;
|
||||
uint16_t Redata = axp192_read_12bit(0x58);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_vbus_voltage()
|
||||
{
|
||||
float ADCLSB = 1.7 / 1000.0;
|
||||
uint16_t Redata = axp192_read_12bit(0x5A);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_vbus_current()
|
||||
{
|
||||
float ADCLSB = 0.375;
|
||||
uint16_t Redata = axp192_read_12bit(0x5C);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_temp()
|
||||
{
|
||||
float ADCLSB = 0.1;
|
||||
const float OFFSET_DEG_C = -144.7;
|
||||
uint16_t Redata = axp192_read_12bit(0x5E);
|
||||
return OFFSET_DEG_C + Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_bat_power()
|
||||
{
|
||||
float VoltageLSB = 1.1;
|
||||
float CurrentLCS = 0.5;
|
||||
uint32_t Redata = axp192_read_24bit(0x70);
|
||||
return VoltageLSB * CurrentLCS * Redata / 1000.0;
|
||||
}
|
||||
|
||||
float axp192_get_bat_charge_current()
|
||||
{
|
||||
float ADCLSB = 0.5;
|
||||
uint16_t Redata = axp192_read_12bit(0x7A);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
float axp192_get_aps_voltage()
|
||||
{
|
||||
float ADCLSB = 1.4 / 1000.0;
|
||||
uint16_t Redata = axp192_read_12bit(0x7E);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_bat_coulomb_input()
|
||||
{
|
||||
uint32_t Redata = axp192_read_32bit(0xB0);
|
||||
return Redata * 65536 * 0.5 / 3600 / 25.0;
|
||||
}
|
||||
|
||||
float axp192_get_bat_coulomb_out()
|
||||
{
|
||||
uint32_t Redata = axp192_read_32bit(0xB4);
|
||||
return Redata * 65536 * 0.5 / 3600 / 25.0;
|
||||
}
|
||||
|
||||
void axp192_set_coulomb_clear()
|
||||
{
|
||||
axp192_write_byte(0xB8, 0x20);
|
||||
}
|
||||
|
||||
void axp192_set_ldo2(bool state)
|
||||
{
|
||||
uint8_t buf = axp192_read_8bit(0x12);
|
||||
if (state == true)
|
||||
buf = (1 << 2) | buf;
|
||||
else
|
||||
buf = ~(1 << 2) & buf;
|
||||
axp192_write_byte(0x12, buf);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _PMW_AXP192_H_
|
||||
#define _PWM_AXP192_H_
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
#define AXP192_ADDRESS 0x34
|
||||
|
||||
void axp192_start(void);
|
||||
void axp192_screen_breath(uint8_t brightness);
|
||||
bool axp192_get_bat_state();
|
||||
|
||||
void axp192_enable_coulombcounter(void);
|
||||
void axp192_disable_coulombcounter(void);
|
||||
void axp192_stop_coulombcounter(void);
|
||||
void axp192_clear_coulombcounter(void);
|
||||
uint32_t axp192_get_coulombcharge_data(void);
|
||||
uint32_t axp192_get_coulombdischarge_data(void);
|
||||
float axp192_get_coulomb_data(void);
|
||||
|
||||
uint8_t axp192_get_btn_press(void);
|
||||
|
||||
// -- sleep
|
||||
void axp192_set_sleep(void);
|
||||
void axp192_deep_sleep(uint64_t time_in_us);
|
||||
void axp192_light_sleep(uint64_t time_in_us);
|
||||
uint8_t axp192_get_warning_leve(void);
|
||||
|
||||
float axp192_get_bat_voltage();
|
||||
float axp192_get_bat_current();
|
||||
float axp192_get_vin_voltage();
|
||||
float axp192_get_vin_current();
|
||||
float axp192_get_vbus_voltage();
|
||||
float axp192_get_vbus_current();
|
||||
float axp192_get_temp();
|
||||
float axp192_get_bat_power();
|
||||
float axp192_get_bat_charge_current();
|
||||
float axp192_get_aps_voltage();
|
||||
float axp192_get_bat_coulomb_input();
|
||||
float axp192_get_bat_coulomb_out();
|
||||
uint8_t axp192_get_warning_level(void);
|
||||
void axp192_set_coulomb_clear();
|
||||
void axp192_set_ldo2(bool state);
|
||||
|
||||
void axp192_write_byte(uint8_t addr, uint8_t data);
|
||||
uint8_t axp192_read_8bit(uint8_t addr);
|
||||
uint16_t axp192_read_12bit(uint8_t addr);
|
||||
uint16_t axp192_read_13bit(uint8_t addr);
|
||||
uint16_t axp192_read_16bit(uint8_t addr);
|
||||
uint32_t axp192_read_24bit(uint8_t addr);
|
||||
uint32_t axp192_read_32bit(uint8_t addr);
|
||||
void axp192_read_buff(uint8_t addr, uint8_t size, uint8_t *buff);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,348 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <driver/spi_master.h>
|
||||
#include <driver/gpio.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "display-gfx.h"
|
||||
|
||||
#include "axp192.h"
|
||||
|
||||
#include "st7735s.h"
|
||||
|
||||
static spi_device_handle_t st7735s_handle;
|
||||
|
||||
bool spi_master_write(uint8_t *data, size_t len, uint8_t dc)
|
||||
{
|
||||
spi_transaction_t spi_trans;
|
||||
esp_err_t ret;
|
||||
|
||||
gpio_set_level(M5_ST7735S_DC_GPIO, dc);
|
||||
|
||||
memset(&spi_trans, 0, sizeof(spi_transaction_t));
|
||||
spi_trans.length = len * 8;
|
||||
spi_trans.tx_buffer = data;
|
||||
ret = spi_device_transmit(st7735s_handle, &spi_trans);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spi_master_write_command(uint8_t cmd)
|
||||
{
|
||||
return spi_master_write(&cmd, 1, SPI_COMMAND_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_data_byte(uint8_t data)
|
||||
{
|
||||
return spi_master_write(&data, 1, SPI_DATA_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_data(uint8_t *data, size_t len)
|
||||
{
|
||||
return spi_master_write(data, len, SPI_DATA_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_addr(uint16_t addr1, uint16_t addr2)
|
||||
{
|
||||
uint8_t data[4];
|
||||
data[0] = (addr1 >> 8) & 0xFF;
|
||||
data[1] = addr1 & 0xFF;
|
||||
data[2] = (addr2 >> 8) & 0xFF;
|
||||
data[3] = addr2 & 0xFF;
|
||||
|
||||
return spi_master_write_data(data, 4);
|
||||
}
|
||||
|
||||
bool spi_master_write_color(uint16_t color, size_t size)
|
||||
{
|
||||
uint8_t data[size * 2];
|
||||
int index = 0;
|
||||
|
||||
uint8_t msbColor = (color >> 8) & 0xFF;
|
||||
uint8_t lsbColor = color & 0xFF;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
data[index++] = msbColor;
|
||||
data[index++] = lsbColor;
|
||||
}
|
||||
return spi_master_write_data(data, size * 2);
|
||||
}
|
||||
|
||||
bool spi_master_write_colors(uint16_t *colors, size_t size)
|
||||
{
|
||||
uint8_t data[size * 2];
|
||||
int index = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
data[index++] = (colors[i] >> 8) & 0xFF;
|
||||
data[index++] = colors[i] & 0xFF;
|
||||
}
|
||||
return spi_master_write_data(data, size * 2);
|
||||
}
|
||||
|
||||
void display_start(void)
|
||||
{
|
||||
|
||||
axp192_start();
|
||||
axp192_screen_breath(0);
|
||||
|
||||
esp_err_t ret;
|
||||
|
||||
gpio_set_direction(M5_ST7735S_CS_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7735S_CS_GPIO, 0);
|
||||
|
||||
gpio_set_direction(M5_ST7735S_DC_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7735S_DC_GPIO, 0);
|
||||
|
||||
gpio_set_direction(M5_ST7735S_RESET_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7735S_RESET_GPIO, 0);
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(M5_ST7735S_RESET_GPIO, 1);
|
||||
|
||||
spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = M5_ST7735S_SCLK_GPIO,
|
||||
.mosi_io_num = M5_ST7735S_MOSI_GPIO,
|
||||
.miso_io_num = -1,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1};
|
||||
|
||||
ret = spi_bus_initialize(HSPI_HOST, &buscfg, 1);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.clock_speed_hz = SPI_MASTER_FREQ_20M,
|
||||
.spics_io_num = M5_ST7735S_CS_GPIO,
|
||||
.queue_size = 7,
|
||||
.flags = SPI_DEVICE_NO_DUMMY,
|
||||
};
|
||||
|
||||
ret = spi_bus_add_device(HSPI_HOST, &devcfg, &st7735s_handle);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
spi_master_write_command(0x01); //Software Reset
|
||||
vTaskDelay(150 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x11); //Sleep Out
|
||||
vTaskDelay(255 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0xB1); //Frame Rate Control (In normal mode/ Full colors)
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
|
||||
spi_master_write_command(0xB2); //Frame Rate Control (In Idle mode/ 8-colors)
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
|
||||
spi_master_write_command(0xB3); //Frame Rate Control (In Partial mode/ full colors)
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
|
||||
spi_master_write_command(0xB4); //Display Inversion Control
|
||||
spi_master_write_data_byte(0x07);
|
||||
|
||||
spi_master_write_command(0xC0); //Power Control 1
|
||||
spi_master_write_data_byte(0xA2);
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x84);
|
||||
|
||||
spi_master_write_command(0xC1); //Power Control 2
|
||||
spi_master_write_data_byte(0xC5);
|
||||
|
||||
spi_master_write_command(0xC2); //Power Control 3 (in Normal mode/ Full colors)
|
||||
spi_master_write_data_byte(0x0A);
|
||||
spi_master_write_data_byte(0x00);
|
||||
|
||||
spi_master_write_command(0xC3); //Power Control 4 (in Idle mode/ 8-colors)
|
||||
spi_master_write_data_byte(0x8A);
|
||||
spi_master_write_data_byte(0x2A);
|
||||
|
||||
spi_master_write_command(0xC4); //Power Control 5 (in Partial mode/ full-colors)
|
||||
spi_master_write_data_byte(0x8A);
|
||||
spi_master_write_data_byte(0xEE);
|
||||
|
||||
spi_master_write_command(0xC5); //VCOM Control 1
|
||||
spi_master_write_data_byte(0x0E);
|
||||
|
||||
spi_master_write_command(0x20); //Display Inversion Off
|
||||
|
||||
spi_master_write_command(0x36); //Memory Data Access Control
|
||||
spi_master_write_data_byte(M5_ST7735S_LANDSCAPE); // landscape + RGB color
|
||||
|
||||
spi_master_write_command(0x3A); //Interface Pixel Format
|
||||
spi_master_write_data_byte(0x05); //16-bit/pixel 65K-Colors(RGB 5-6-5-bit Input)
|
||||
|
||||
spi_master_write_command(0x2A); //Column Address Set
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x81);
|
||||
|
||||
spi_master_write_command(0x2B); //Row Address Set
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0xA0);
|
||||
|
||||
spi_master_write_command(0x21); //Display Inversion On
|
||||
|
||||
spi_master_write_command(0xE0); //Gamma (‘+’polarity) Correction Characteristics Setting
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x1C);
|
||||
spi_master_write_data_byte(0x07);
|
||||
spi_master_write_data_byte(0x12);
|
||||
spi_master_write_data_byte(0x37);
|
||||
spi_master_write_data_byte(0x32);
|
||||
spi_master_write_data_byte(0x29);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
spi_master_write_data_byte(0x29);
|
||||
spi_master_write_data_byte(0x25);
|
||||
spi_master_write_data_byte(0x2B);
|
||||
spi_master_write_data_byte(0x39);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x03);
|
||||
spi_master_write_data_byte(0x10);
|
||||
|
||||
spi_master_write_command(0xE1); //Gamma ‘-’polarity Correction Characteristics Setting
|
||||
spi_master_write_data_byte(0x03);
|
||||
spi_master_write_data_byte(0x1D);
|
||||
spi_master_write_data_byte(0x07);
|
||||
spi_master_write_data_byte(0x06);
|
||||
spi_master_write_data_byte(0x2E);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x29);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
spi_master_write_data_byte(0x2E);
|
||||
spi_master_write_data_byte(0x2E);
|
||||
spi_master_write_data_byte(0x37);
|
||||
spi_master_write_data_byte(0x3F);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x10);
|
||||
|
||||
spi_master_write_command(0x13); //Normal Display Mode On
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x29); //Display On
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
|
||||
axp192_screen_breath(10);
|
||||
}
|
||||
|
||||
void display_clear_line(uint8_t line, bool invert)
|
||||
{
|
||||
uint16_t _x1 = 0 + M5_ST7735S_OFFSETX;
|
||||
uint16_t _x2 = M5_ST7735S_WIDTH + M5_ST7735S_OFFSETX - 1;
|
||||
uint16_t _y1 = line * 8 + M5_ST7735S_OFFSETY + M5_ST7735S_INTERFACE_OFFSETY;
|
||||
uint16_t _y2 = line * 8 + 8 + M5_ST7735S_OFFSETY - 1 + M5_ST7735S_INTERFACE_OFFSETY;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); // Memory Write
|
||||
for (int i = _x1; i <= _x2; i++)
|
||||
{
|
||||
uint16_t size = _y2 - _y1 + 1;
|
||||
spi_master_write_color(invert ? display_get_color() : BLACK, size);
|
||||
}
|
||||
}
|
||||
|
||||
void display_clear(void)
|
||||
{
|
||||
uint16_t _x1 = 0 + M5_ST7735S_OFFSETX;
|
||||
uint16_t _x2 = M5_ST7735S_WIDTH + M5_ST7735S_OFFSETX - 1;
|
||||
uint16_t _y1 = 0 + M5_ST7735S_OFFSETY;
|
||||
uint16_t _y2 = M5_ST7735S_HEIGHT + M5_ST7735S_OFFSETY - 1;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); // Memory Write
|
||||
for (int i = _x1; i <= _x2; i++)
|
||||
{
|
||||
uint16_t size = _y2 - _y1 + 1;
|
||||
spi_master_write_color(BLACK, size);
|
||||
}
|
||||
}
|
||||
|
||||
void display_on(bool on)
|
||||
{
|
||||
axp192_screen_breath(on ? 10 : 0);
|
||||
}
|
||||
|
||||
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert)
|
||||
{
|
||||
uint16_t _x1 = offset + M5_ST7735S_OFFSETX + M5_ST7735S_INTERFACE_OFFSETX;
|
||||
uint16_t _x2 = offset + length + M5_ST7735S_OFFSETX - 1 + M5_ST7735S_INTERFACE_OFFSETX;
|
||||
uint16_t _y1 = line * 8 + M5_ST7735S_OFFSETY + M5_ST7735S_INTERFACE_OFFSETY;
|
||||
uint16_t _y2 = line * 8 + 8 + M5_ST7735S_OFFSETY - 1 + M5_ST7735S_INTERFACE_OFFSETY;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); //Memory Write
|
||||
|
||||
uint8_t msbColor = (display_get_color() >> 8) & 0xFF;
|
||||
uint8_t lsbColor = display_get_color() & 0xFF;
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
uint8_t color[length * 2];
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
bool bit = (data[i] & (1 << j));
|
||||
if (invert)
|
||||
{
|
||||
bit = !bit;
|
||||
}
|
||||
color[index++] = bit ? msbColor : 0x00;
|
||||
color[index++] = bit ? lsbColor : 0x00;
|
||||
}
|
||||
spi_master_write_data(color, length * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void display_flipped(bool flipped)
|
||||
{
|
||||
spi_master_write_command(0x36); //Memory Data Access Control
|
||||
if (flipped)
|
||||
{
|
||||
spi_master_write_data_byte(M5_ST7735S_LANDSCAPE_FLIPPED);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_master_write_data_byte(M5_ST7735S_LANDSCAPE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef DISPLAY_ST7735S_H_
|
||||
#define DISPLAY_ST7735S_H_
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
// M5stickC
|
||||
#define M5_ST7735S_WIDTH 160
|
||||
#define M5_ST7735S_HEIGHT 80
|
||||
#define M5_ST7735S_MOSI_GPIO 15
|
||||
#define M5_ST7735S_SCLK_GPIO 13
|
||||
#define M5_ST7735S_CS_GPIO 5
|
||||
#define M5_ST7735S_DC_GPIO 23
|
||||
#define M5_ST7735S_RESET_GPIO 18
|
||||
|
||||
#define M5_ST7735S_OFFSETX 1
|
||||
#define M5_ST7735S_OFFSETY 26
|
||||
|
||||
#define M5_ST7735S_INTERFACE_OFFSETX 16
|
||||
#define M5_ST7735S_INTERFACE_OFFSETY 8
|
||||
|
||||
#define M5_ST7735S_LANDSCAPE_FLIPPED 0x68
|
||||
#define M5_ST7735S_LANDSCAPE 0xA8
|
||||
|
||||
#define SPI_COMMAND_MODE 0
|
||||
#define SPI_DATA_MODE 1
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,281 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <driver/spi_master.h>
|
||||
#include <driver/gpio.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "display-gfx.h"
|
||||
|
||||
#include "axp192.h"
|
||||
|
||||
#include "st7789.h"
|
||||
|
||||
static spi_device_handle_t st7789_handle;
|
||||
|
||||
bool spi_master_write(uint8_t *data, size_t len, uint8_t dc)
|
||||
{
|
||||
spi_transaction_t spi_trans;
|
||||
|
||||
gpio_set_level(M5_ST7789_DC_GPIO, dc);
|
||||
|
||||
memset(&spi_trans, 0, sizeof(spi_transaction_t));
|
||||
spi_trans.length = len * 8;
|
||||
spi_trans.tx_buffer = data;
|
||||
spi_device_transmit(st7789_handle, &spi_trans);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spi_master_write_command(uint8_t cmd)
|
||||
{
|
||||
return spi_master_write(&cmd, 1, SPI_COMMAND_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_data_byte(uint8_t data)
|
||||
{
|
||||
return spi_master_write(&data, 1, SPI_DATA_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_data(uint8_t *data, size_t len)
|
||||
{
|
||||
return spi_master_write(data, len, SPI_DATA_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_addr(uint16_t addr1, uint16_t addr2)
|
||||
{
|
||||
uint8_t data[4];
|
||||
data[0] = (addr1 >> 8) & 0xFF;
|
||||
data[1] = addr1 & 0xFF;
|
||||
data[2] = (addr2 >> 8) & 0xFF;
|
||||
data[3] = addr2 & 0xFF;
|
||||
|
||||
return spi_master_write_data(data, 4);
|
||||
}
|
||||
|
||||
bool spi_master_write_color(uint16_t color, size_t size)
|
||||
{
|
||||
uint8_t data[size * 2];
|
||||
int index = 0;
|
||||
|
||||
uint8_t msbColor = (color >> 8) & 0xFF;
|
||||
uint8_t lsbColor = color & 0xFF;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
data[index++] = msbColor;
|
||||
data[index++] = lsbColor;
|
||||
}
|
||||
return spi_master_write_data(data, size * 2);
|
||||
}
|
||||
|
||||
bool spi_master_write_colors(uint16_t *colors, size_t size)
|
||||
{
|
||||
uint8_t data[size * 2];
|
||||
int index = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
data[index++] = (colors[i] >> 8) & 0xFF;
|
||||
data[index++] = colors[i] & 0xFF;
|
||||
}
|
||||
return spi_master_write_data(data, size * 2);
|
||||
}
|
||||
|
||||
void display_start(void)
|
||||
{
|
||||
|
||||
axp192_start();
|
||||
axp192_screen_breath(0);
|
||||
|
||||
esp_err_t ret;
|
||||
|
||||
gpio_pad_select_gpio(M5_ST7789_CS_GPIO);
|
||||
gpio_set_direction(M5_ST7789_CS_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7789_CS_GPIO, 0);
|
||||
|
||||
gpio_pad_select_gpio(M5_ST7789_DC_GPIO);
|
||||
gpio_set_direction(M5_ST7789_DC_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7789_DC_GPIO, 0);
|
||||
|
||||
gpio_pad_select_gpio(M5_ST7789_RESET_GPIO);
|
||||
gpio_set_direction(M5_ST7789_RESET_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7789_RESET_GPIO, 1);
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(M5_ST7789_RESET_GPIO, 0);
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(M5_ST7789_RESET_GPIO, 1);
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
|
||||
gpio_pad_select_gpio(M5_ST7789_BL_GPIO);
|
||||
gpio_set_direction(M5_ST7789_BL_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7789_BL_GPIO, 0);
|
||||
|
||||
spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = M5_ST7789_SCLK_GPIO,
|
||||
.mosi_io_num = M5_ST7789_MOSI_GPIO,
|
||||
.miso_io_num = -1,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1};
|
||||
|
||||
ret = spi_bus_initialize(HSPI_HOST, &buscfg, 1);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.clock_speed_hz = SPI_MASTER_FREQ_20M,
|
||||
.queue_size = 7,
|
||||
.mode = 2,
|
||||
.flags = SPI_DEVICE_NO_DUMMY,
|
||||
};
|
||||
|
||||
devcfg.spics_io_num = M5_ST7789_CS_GPIO;
|
||||
|
||||
ret = spi_bus_add_device(HSPI_HOST, &devcfg, &st7789_handle);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
spi_master_write_command(0x01); //Software Reset
|
||||
vTaskDelay(150 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x11); //Sleep Out
|
||||
vTaskDelay(255 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x3A); //Interface Pixel Format
|
||||
spi_master_write_data_byte(0x55);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
// landscape RGB
|
||||
spi_master_write_command(0x36); //Memory Data Access Control
|
||||
spi_master_write_data_byte(M5_ST7789_LANDSCAPE);
|
||||
|
||||
spi_master_write_command(0x2A); //Column Address Set
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0xF0);
|
||||
|
||||
spi_master_write_command(0x2B); //Row Address Set
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0xF0);
|
||||
|
||||
spi_master_write_command(0x21); //Display Inversion On
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x13); //Normal Display Mode On
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x29); //Display ON
|
||||
vTaskDelay(255 / portTICK_PERIOD_MS);
|
||||
|
||||
gpio_set_level(M5_ST7789_BL_GPIO, 1);
|
||||
|
||||
axp192_screen_breath(10);
|
||||
}
|
||||
|
||||
void display_flipped(bool flipped)
|
||||
{
|
||||
spi_master_write_command(0x36); //Memory Data Access Control
|
||||
if (flipped)
|
||||
{
|
||||
spi_master_write_data_byte(M5_ST7789_LANDSCAPE_FLIPPED);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_master_write_data_byte(M5_ST7789_LANDSCAPE);
|
||||
}
|
||||
}
|
||||
|
||||
void display_clear_line(uint8_t line, bool invert)
|
||||
{
|
||||
uint16_t _x1 = 0 + M5_ST7789_OFFSETX;
|
||||
uint16_t _x2 = M5_ST7789_WIDTH + M5_ST7789_OFFSETX - 1;
|
||||
uint16_t _y1 = line * 8 + M5_ST7789_OFFSETY + M5_ST7789_INTERFACE_OFFSETY;
|
||||
uint16_t _y2 = line * 8 + 8 + M5_ST7789_OFFSETY - 1 + M5_ST7789_INTERFACE_OFFSETY;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); // Memory Write
|
||||
for (int i = _x1; i <= _x2; i++)
|
||||
{
|
||||
uint16_t size = _y2 - _y1 + 1;
|
||||
spi_master_write_color(invert ? display_get_color() : BLACK, size);
|
||||
}
|
||||
}
|
||||
|
||||
void display_clear(void)
|
||||
{
|
||||
uint16_t _x1 = 0 + M5_ST7789_OFFSETX;
|
||||
uint16_t _x2 = M5_ST7789_WIDTH + M5_ST7789_OFFSETX - 1;
|
||||
uint16_t _y1 = 0 + M5_ST7789_OFFSETY;
|
||||
uint16_t _y2 = M5_ST7789_HEIGHT + M5_ST7789_OFFSETY - 1;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); // Memory Write
|
||||
for (int i = _x1; i <= _x2; i++)
|
||||
{
|
||||
uint16_t size = _y2 - _y1 + 1;
|
||||
spi_master_write_color(BLACK, size);
|
||||
}
|
||||
}
|
||||
|
||||
void display_on(bool on)
|
||||
{
|
||||
axp192_screen_breath(on ? 10 : 0);
|
||||
}
|
||||
|
||||
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert)
|
||||
{
|
||||
uint16_t _x1 = offset + M5_ST7789_OFFSETX + M5_ST7789_INTERFACE_OFFSETX;
|
||||
uint16_t _x2 = offset + length + M5_ST7789_OFFSETX - 1 + M5_ST7789_INTERFACE_OFFSETX;
|
||||
uint16_t _y1 = line * 8 + M5_ST7789_OFFSETY + M5_ST7789_INTERFACE_OFFSETY;
|
||||
uint16_t _y2 = line * 8 + 8 + M5_ST7789_OFFSETY - 1 + M5_ST7789_INTERFACE_OFFSETY;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); //Memory Write
|
||||
|
||||
uint8_t msbColor = (display_get_color() >> 8) & 0xFF;
|
||||
uint8_t lsbColor = display_get_color() & 0xFF;
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
uint8_t color[length * 2];
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
bool bit = (data[i] & (1 << j));
|
||||
if (invert)
|
||||
{
|
||||
bit = !bit;
|
||||
}
|
||||
color[index++] = bit ? msbColor : 0x00;
|
||||
color[index++] = bit ? lsbColor : 0x00;
|
||||
}
|
||||
spi_master_write_data(color, length * 2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef DISPLAY_ST7789_H_
|
||||
#define DISPLAY_ST7789_H_
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
// M5stickC PLUS
|
||||
#define M5_ST7789_WIDTH 240
|
||||
#define M5_ST7789_HEIGHT 135
|
||||
#define M5_ST7789_MOSI_GPIO 15
|
||||
#define M5_ST7789_SCLK_GPIO 13
|
||||
#define M5_ST7789_CS_GPIO 5
|
||||
#define M5_ST7789_DC_GPIO 23
|
||||
#define M5_ST7789_RESET_GPIO 18
|
||||
#define M5_ST7789_BL_GPIO 32
|
||||
#define M5_ST7789_OFFSETX 40
|
||||
#define M5_ST7789_OFFSETY 52
|
||||
|
||||
#define M5_ST7789_LANDSCAPE 0x60
|
||||
#define M5_ST7789_LANDSCAPE_FLIPPED 0xA0
|
||||
|
||||
#define M5_ST7789_INTERFACE_OFFSETX 56
|
||||
#define M5_ST7789_INTERFACE_OFFSETY 35
|
||||
|
||||
#define SPI_COMMAND_MODE 0
|
||||
#define SPI_DATA_MODE 1
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,346 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <driver/spi_master.h>
|
||||
#include <driver/gpio.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "display-gfx.h"
|
||||
|
||||
#include "st7735.h"
|
||||
|
||||
static spi_device_handle_t st7735s_handle;
|
||||
|
||||
bool spi_master_write(uint8_t *data, size_t len, uint8_t dc)
|
||||
{
|
||||
spi_transaction_t spi_trans;
|
||||
esp_err_t ret;
|
||||
|
||||
gpio_set_level(TTGO_T_WRISTBAND_DC_GPIO, dc);
|
||||
|
||||
memset(&spi_trans, 0, sizeof(spi_transaction_t));
|
||||
spi_trans.length = len * 8;
|
||||
spi_trans.tx_buffer = data;
|
||||
ret = spi_device_transmit(st7735s_handle, &spi_trans);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spi_master_write_command(uint8_t cmd)
|
||||
{
|
||||
return spi_master_write(&cmd, 1, SPI_COMMAND_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_data_byte(uint8_t data)
|
||||
{
|
||||
return spi_master_write(&data, 1, SPI_DATA_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_data(uint8_t *data, size_t len)
|
||||
{
|
||||
return spi_master_write(data, len, SPI_DATA_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_addr(uint16_t addr1, uint16_t addr2)
|
||||
{
|
||||
uint8_t data[4];
|
||||
data[0] = (addr1 >> 8) & 0xFF;
|
||||
data[1] = addr1 & 0xFF;
|
||||
data[2] = (addr2 >> 8) & 0xFF;
|
||||
data[3] = addr2 & 0xFF;
|
||||
|
||||
return spi_master_write_data(data, 4);
|
||||
}
|
||||
|
||||
bool spi_master_write_color(uint16_t color, size_t size)
|
||||
{
|
||||
uint8_t data[size * 2];
|
||||
int index = 0;
|
||||
|
||||
uint8_t msbColor = (color >> 8) & 0xFF;
|
||||
uint8_t lsbColor = color & 0xFF;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
data[index++] = msbColor;
|
||||
data[index++] = lsbColor;
|
||||
}
|
||||
return spi_master_write_data(data, size * 2);
|
||||
}
|
||||
|
||||
bool spi_master_write_colors(uint16_t *colors, size_t size)
|
||||
{
|
||||
uint8_t data[size * 2];
|
||||
int index = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
data[index++] = (colors[i] >> 8) & 0xFF;
|
||||
data[index++] = colors[i] & 0xFF;
|
||||
}
|
||||
return spi_master_write_data(data, size * 2);
|
||||
}
|
||||
|
||||
void display_start(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
gpio_set_direction(TTGO_T_WRISTBAND_CS_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(TTGO_T_WRISTBAND_CS_GPIO, 0);
|
||||
|
||||
gpio_set_direction(TTGO_T_WRISTBAND_DC_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(TTGO_T_WRISTBAND_DC_GPIO, 0);
|
||||
|
||||
gpio_set_direction(TTGO_T_WRISTBAND_RESET_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(TTGO_T_WRISTBAND_RESET_GPIO, 0);
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(TTGO_T_WRISTBAND_RESET_GPIO, 1);
|
||||
|
||||
spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = TTGO_T_WRISTBAND_SCLK_GPIO,
|
||||
.mosi_io_num = TTGO_T_WRISTBAND_MOSI_GPIO,
|
||||
.miso_io_num = -1,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1};
|
||||
|
||||
ret = spi_bus_initialize(HSPI_HOST, &buscfg, 1);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.clock_speed_hz = SPI_MASTER_FREQ_20M,
|
||||
.spics_io_num = TTGO_T_WRISTBAND_CS_GPIO,
|
||||
.queue_size = 7,
|
||||
.flags = SPI_DEVICE_NO_DUMMY,
|
||||
};
|
||||
|
||||
ret = spi_bus_add_device(HSPI_HOST, &devcfg, &st7735s_handle);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
spi_master_write_command(0x01); //Software Reset
|
||||
vTaskDelay(150 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x11); //Sleep Out
|
||||
vTaskDelay(255 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0xB1); //Frame Rate Control (In normal mode/ Full colors)
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
|
||||
spi_master_write_command(0xB2); //Frame Rate Control (In Idle mode/ 8-colors)
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
|
||||
spi_master_write_command(0xB3); //Frame Rate Control (In Partial mode/ full colors)
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
|
||||
spi_master_write_command(0xB4); //Display Inversion Control
|
||||
spi_master_write_data_byte(0x07);
|
||||
|
||||
spi_master_write_command(0xC0); //Power Control 1
|
||||
spi_master_write_data_byte(0xA2);
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x84);
|
||||
|
||||
spi_master_write_command(0xC1); //Power Control 2
|
||||
spi_master_write_data_byte(0xC5);
|
||||
|
||||
spi_master_write_command(0xC2); //Power Control 3 (in Normal mode/ Full colors)
|
||||
spi_master_write_data_byte(0x0A);
|
||||
spi_master_write_data_byte(0x00);
|
||||
|
||||
spi_master_write_command(0xC3); //Power Control 4 (in Idle mode/ 8-colors)
|
||||
spi_master_write_data_byte(0x8A);
|
||||
spi_master_write_data_byte(0x2A);
|
||||
|
||||
spi_master_write_command(0xC4); //Power Control 5 (in Partial mode/ full-colors)
|
||||
spi_master_write_data_byte(0x8A);
|
||||
spi_master_write_data_byte(0xEE);
|
||||
|
||||
spi_master_write_command(0xC5); //VCOM Control 1
|
||||
spi_master_write_data_byte(0x0E);
|
||||
|
||||
spi_master_write_command(0x20); //Display Inversion Off
|
||||
|
||||
spi_master_write_command(0x36); //Memory Data Access Control
|
||||
spi_master_write_data_byte(TTGO_T_WRISTBAND_LANDSCAPE); // landscape + RGB color
|
||||
|
||||
spi_master_write_command(0x3A); //Interface Pixel Format
|
||||
spi_master_write_data_byte(0x05); //16-bit/pixel 65K-Colors(RGB 5-6-5-bit Input)
|
||||
|
||||
spi_master_write_command(0x2A); //Column Address Set
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x81);
|
||||
|
||||
spi_master_write_command(0x2B); //Row Address Set
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0xA0);
|
||||
|
||||
spi_master_write_command(0x21); //Display Inversion On
|
||||
|
||||
spi_master_write_command(0xE0); //Gamma (‘+’polarity) Correction Characteristics Setting
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x1C);
|
||||
spi_master_write_data_byte(0x07);
|
||||
spi_master_write_data_byte(0x12);
|
||||
spi_master_write_data_byte(0x37);
|
||||
spi_master_write_data_byte(0x32);
|
||||
spi_master_write_data_byte(0x29);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
spi_master_write_data_byte(0x29);
|
||||
spi_master_write_data_byte(0x25);
|
||||
spi_master_write_data_byte(0x2B);
|
||||
spi_master_write_data_byte(0x39);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x03);
|
||||
spi_master_write_data_byte(0x10);
|
||||
|
||||
spi_master_write_command(0xE1); //Gamma ‘-’polarity Correction Characteristics Setting
|
||||
spi_master_write_data_byte(0x03);
|
||||
spi_master_write_data_byte(0x1D);
|
||||
spi_master_write_data_byte(0x07);
|
||||
spi_master_write_data_byte(0x06);
|
||||
spi_master_write_data_byte(0x2E);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x29);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
spi_master_write_data_byte(0x2E);
|
||||
spi_master_write_data_byte(0x2E);
|
||||
spi_master_write_data_byte(0x37);
|
||||
spi_master_write_data_byte(0x3F);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x10);
|
||||
|
||||
spi_master_write_command(0x13); //Normal Display Mode On
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x29); //Display On
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
|
||||
gpio_pad_select_gpio(TTGO_T_WRISTBAND__BL_GPIO);
|
||||
gpio_set_direction(TTGO_T_WRISTBAND__BL_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(TTGO_T_WRISTBAND__BL_GPIO, 1);
|
||||
}
|
||||
|
||||
void display_clear_line(uint8_t line, bool invert)
|
||||
{
|
||||
uint16_t _x1 = 0 + TTGO_T_WRISTBAND_OFFSETX;
|
||||
uint16_t _x2 = TTGO_T_WRISTBAND_WIDTH + TTGO_T_WRISTBAND_OFFSETX - 1;
|
||||
uint16_t _y1 = line * 8 + TTGO_T_WRISTBAND_OFFSETY + TTGO_T_WRISTBAND_INTERFACE_OFFSETY;
|
||||
uint16_t _y2 = line * 8 + 8 + TTGO_T_WRISTBAND_OFFSETY - 1 + TTGO_T_WRISTBAND_INTERFACE_OFFSETY;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); // Memory Write
|
||||
for (int i = _x1; i <= _x2; i++)
|
||||
{
|
||||
uint16_t size = _y2 - _y1 + 1;
|
||||
spi_master_write_color(invert ? display_get_color() : BLACK, size);
|
||||
}
|
||||
}
|
||||
|
||||
void display_clear(void)
|
||||
{
|
||||
uint16_t _x1 = 0 + TTGO_T_WRISTBAND_OFFSETX;
|
||||
uint16_t _x2 = TTGO_T_WRISTBAND_WIDTH + TTGO_T_WRISTBAND_OFFSETX - 1;
|
||||
uint16_t _y1 = 0 + TTGO_T_WRISTBAND_OFFSETY;
|
||||
uint16_t _y2 = TTGO_T_WRISTBAND_HEIGHT + TTGO_T_WRISTBAND_OFFSETY - 1;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); // Memory Write
|
||||
for (int i = _x1; i <= _x2; i++)
|
||||
{
|
||||
uint16_t size = _y2 - _y1 + 1;
|
||||
spi_master_write_color(BLACK, size);
|
||||
}
|
||||
}
|
||||
|
||||
void display_on(bool on)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert)
|
||||
{
|
||||
uint16_t _x1 = offset + TTGO_T_WRISTBAND_OFFSETX + TTGO_T_WRISTBAND_INTERFACE_OFFSETX;
|
||||
uint16_t _x2 = offset + length + TTGO_T_WRISTBAND_OFFSETX - 1 + TTGO_T_WRISTBAND_INTERFACE_OFFSETX;
|
||||
uint16_t _y1 = line * 8 + TTGO_T_WRISTBAND_OFFSETY + TTGO_T_WRISTBAND_INTERFACE_OFFSETY;
|
||||
uint16_t _y2 = line * 8 + 8 + TTGO_T_WRISTBAND_OFFSETY - 1 + TTGO_T_WRISTBAND_INTERFACE_OFFSETY;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); //Memory Write
|
||||
|
||||
uint8_t msbColor = (display_get_color() >> 8) & 0xFF;
|
||||
uint8_t lsbColor = display_get_color() & 0xFF;
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
uint8_t color[length * 2];
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
bool bit = (data[i] & (1 << j));
|
||||
if (invert)
|
||||
{
|
||||
bit = !bit;
|
||||
}
|
||||
color[index++] = bit ? msbColor : 0x00;
|
||||
color[index++] = bit ? lsbColor : 0x00;
|
||||
}
|
||||
spi_master_write_data(color, length * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void display_flipped(bool flipped)
|
||||
{
|
||||
spi_master_write_command(0x36); //Memory Data Access Control
|
||||
if (flipped)
|
||||
{
|
||||
spi_master_write_data_byte(TTGO_T_WRISTBAND_LANDSCAPE_FLIPPED);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_master_write_data_byte(TTGO_T_WRISTBAND_LANDSCAPE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef DISPLAY_ST7735_H_
|
||||
#define DISPLAY_ST7735_H_
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
// M5stickC
|
||||
#define TTGO_T_WRISTBAND_WIDTH 160
|
||||
#define TTGO_T_WRISTBAND_HEIGHT 80
|
||||
#define TTGO_T_WRISTBAND_MOSI_GPIO 19
|
||||
#define TTGO_T_WRISTBAND_SCLK_GPIO 18
|
||||
#define TTGO_T_WRISTBAND_CS_GPIO 5
|
||||
#define TTGO_T_WRISTBAND_DC_GPIO 23
|
||||
#define TTGO_T_WRISTBAND_RESET_GPIO 26
|
||||
#define TTGO_T_WRISTBAND__BL_GPIO 27
|
||||
|
||||
#define TTGO_T_WRISTBAND_OFFSETX 1
|
||||
#define TTGO_T_WRISTBAND_OFFSETY 26
|
||||
|
||||
#define TTGO_T_WRISTBAND_INTERFACE_OFFSETX 16
|
||||
#define TTGO_T_WRISTBAND_INTERFACE_OFFSETY 8
|
||||
|
||||
#define TTGO_T_WRISTBAND_LANDSCAPE_FLIPPED 0x68
|
||||
#define TTGO_T_WRISTBAND_LANDSCAPE 0xA8
|
||||
|
||||
#define SPI_COMMAND_MODE 0
|
||||
#define SPI_DATA_MODE 1
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user