Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@ elseif(CONFIG_BOARD_TYPE_WAVESHARE_S3_TOUCH_AMOLED_2_06)
set(BUILTIN_TEXT_FONT font_puhui_basic_30_4)
set(BUILTIN_ICON_FONT font_awesome_30_4)
set(DEFAULT_EMOJI_COLLECTION twemoji_64)
elseif(CONFIG_BOARD_TYPE_WAVESHARE_C6_TOUCH_AMOLED_2_06)
set(BOARD_TYPE "waveshare-c6-touch-amoled-2.06")
set(BUILTIN_TEXT_FONT font_puhui_basic_30_4)
set(BUILTIN_ICON_FONT font_awesome_30_4)
set(DEFAULT_EMOJI_COLLECTION twemoji_64)
elseif(CONFIG_BOARD_TYPE_WAVESHARE_S3_TOUCH_LCD_4B)
set(BOARD_TYPE "waveshare-s3-touch-lcd-4b")
set(BUILTIN_TEXT_FONT font_puhui_basic_30_4)
Expand Down
3 changes: 3 additions & 0 deletions main/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ choice BOARD_TYPE
config BOARD_TYPE_WAVESHARE_S3_TOUCH_AMOLED_2_06
bool "Waveshare ESP32-S3-Touch-AMOLED-2.06"
depends on IDF_TARGET_ESP32S3
config BOARD_TYPE_WAVESHARE_C6_TOUCH_AMOLED_2_06
bool "Waveshare ESP32-C6-Touch-AMOLED-2.06"
depends on IDF_TARGET_ESP32C6
config BOARD_TYPE_WAVESHARE_S3_TOUCH_AMOLED_1_75
bool "Waveshare ESP32-S3-Touch-AMOLED-1.75"
depends on IDF_TARGET_ESP32S3
Expand Down
4 changes: 4 additions & 0 deletions main/boards/waveshare-c6-touch-amoled-2.06/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Waveshare ESP32-C6-Touch-AMOLED-2.06


[ESP32-S3-Touch-AMOLED-2.06](https://www.waveshare.com/esp32-c6-touch-amoled-2.06.htm) is a high-performance wearable watch-shaped development board launched by Waveshare. This product is based on the ESP32-C6 microcontroller and integrates a 2.06-inch capacitive touch high-definition AMOLED screen, a six-axis sensor, RTC, audio codec chip, and power management, among other functional modules. With a custom case, its appearance is consistent with that of a smartwatch, and it is specifically designed for prototype development and functional verification of wearable applications.
47 changes: 47 additions & 0 deletions main/boards/waveshare-c6-touch-amoled-2.06/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef _BOARD_CONFIG_H_
#define _BOARD_CONFIG_H_

#include <driver/gpio.h>


#define AUDIO_INPUT_SAMPLE_RATE 24000
#define AUDIO_OUTPUT_SAMPLE_RATE 24000

#define AUDIO_INPUT_REFERENCE false

#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_19
#define AUDIO_I2S_GPIO_WS GPIO_NUM_22
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_20
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_21
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_23

#define AUDIO_CODEC_PA_PIN GPIO_NUM_6
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_8
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_7
#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR
#define AUDIO_CODEC_ES7210_ADDR ES7210_CODEC_DEFAULT_ADDR

#define BOOT_BUTTON_GPIO GPIO_NUM_9
#define PWR_BUTTON_GPIO GPIO_NUM_18

#define LCD_CS GPIO_NUM_5
#define LCD_PCLK GPIO_NUM_0
#define LCD_D0 GPIO_NUM_1
#define LCD_D1 GPIO_NUM_2
#define LCD_D2 GPIO_NUM_3
#define LCD_D3 GPIO_NUM_4
#define LCD_RST GPIO_NUM_11
#define LCD_LIGHT (-1)

#define EXAMPLE_LCD_H_RES 410
#define EXAMPLE_LCD_V_RES 502

#define DISPLAY_MIRROR_X false
#define DISPLAY_MIRROR_Y false
#define DISPLAY_SWAP_XY false

#define DISPLAY_OFFSET_X 0
#define DISPLAY_OFFSET_Y 0


#endif // _BOARD_CONFIG_H_
11 changes: 11 additions & 0 deletions main/boards/waveshare-c6-touch-amoled-2.06/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"target": "esp32s3",
"builds": [
{
"name": "waveshare-c6-touch-amoled-2.06",
"sdkconfig_append": [
"CONFIG_USE_ESP_WAKE_WORD=y"
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
#include "wifi_board.h"
#include "application.h"
#include "button.h"
#include "config.h"
#include "codecs/box_audio_codec.h"

#include <esp_log.h>
#include <esp_lcd_panel_vendor.h>
#include <driver/i2c_master.h>
#include <driver/spi_common.h>
#include <wifi_station.h>
#include "esp_lcd_sh8601.h"
#include "display/lcd_display.h"
#include "mcp_server.h"
#include "lvgl.h"

#define TAG "waveshare_c6_amoled_2_06"

static const sh8601_lcd_init_cmd_t lcd_init_cmds[] =
{
{0x11, (uint8_t []){0x00}, 0, 80},
{0xC4, (uint8_t []){0x80}, 1, 0},
{0x53, (uint8_t []){0x20}, 1, 1},
{0x63, (uint8_t []){0xFF}, 1, 1},
{0x51, (uint8_t []){0x00}, 1, 1},
{0x29, (uint8_t []){0x00}, 0, 10},
{0x51, (uint8_t []){0xFF}, 1, 0},
};

class CustomLcdDisplay : public SpiLcdDisplay {
public:
static void MyDrawEventCb(lv_event_t *e) {
lv_area_t *area = (lv_area_t *)lv_event_get_param(e);
uint16_t x1 = area->x1;
uint16_t x2 = area->x2;
uint16_t y1 = area->y1;
uint16_t y2 = area->y2;
// round the start of coordinate down to the nearest 2M number
area->x1 = (x1 >> 1) << 1;
area->y1 = (y1 >> 1) << 1;
// round the end of coordinate up to the nearest 2N+1 number
area->x2 = ((x2 >> 1) << 1) + 1;
area->y2 = ((y2 >> 1) << 1) + 1;
}

CustomLcdDisplay(esp_lcd_panel_io_handle_t io_handle,
esp_lcd_panel_handle_t panel_handle,
int width,
int height,
int offset_x,
int offset_y,
bool mirror_x,
bool mirror_y,
bool swap_xy)
: SpiLcdDisplay(io_handle, panel_handle,
width, height, offset_x, offset_y, mirror_x, mirror_y, swap_xy) {
DisplayLockGuard lock(this);
lv_obj_set_style_pad_left(status_bar_, LV_HOR_RES* 0.1, 0);
lv_obj_set_style_pad_right(status_bar_, LV_HOR_RES* 0.1, 0);
lv_display_add_event_cb(display_, MyDrawEventCb, LV_EVENT_INVALIDATE_AREA, NULL);
}
};

class CustomBoard : public WifiBoard {
private:
i2c_master_bus_handle_t i2c_bus_;
Button boot_button_;
Button pwr_button_;
esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_panel_io_handle_t io_handle = NULL;
CustomLcdDisplay* display_;
uint8_t pwr_flag = 0;

void InitializeI2c() {
// Initialize I2C peripheral
i2c_master_bus_config_t i2c_bus_cfg = {
.i2c_port = (i2c_port_t)0,
.sda_io_num = AUDIO_CODEC_I2C_SDA_PIN,
.scl_io_num = AUDIO_CODEC_I2C_SCL_PIN,
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.intr_priority = 0,
.trans_queue_depth = 0,
.flags = {
.enable_internal_pullup = 1,
},
};
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &i2c_bus_));
}

void InitializeSpi() {
spi_bus_config_t buscfg = {
.data0_io_num = LCD_D0,
.data1_io_num = LCD_D1,
.sclk_io_num = LCD_PCLK,
.data2_io_num = LCD_D2,
.data3_io_num = LCD_D3,
.max_transfer_sz = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * sizeof(uint16_t),
};
ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO));
}

void InitializeLcdDisplay() {
const esp_lcd_panel_io_spi_config_t io_config = {
.cs_gpio_num = LCD_CS,
.dc_gpio_num = -1,
.spi_mode = 0,
.pclk_hz = 40 * 1000 * 1000,
.trans_queue_depth = 4,
.on_color_trans_done = NULL,
.user_ctx = NULL,
.lcd_cmd_bits = 32,
.lcd_param_bits = 8,
.flags = {
.quad_mode = true,
},
};
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &io_handle));
sh8601_vendor_config_t vendor_config = {
.init_cmds = lcd_init_cmds, // Uncomment these line if use custom initialization commands
.init_cmds_size = sizeof(lcd_init_cmds) / sizeof(lcd_init_cmds[0]), // sizeof(axs15231b_lcd_init_cmd_t),
.flags =
{
.use_qspi_interface = 1,
},
};
const esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = LCD_RST,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, // Implemented by LCD command `36h`
.bits_per_pixel = 16, // Implemented by LCD command `3Ah` (16/18)
.vendor_config = &vendor_config,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_sh8601(io_handle, &panel_config, &panel_handle));
esp_lcd_panel_set_gap(panel_handle,0x16,0);
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
display_ = new CustomLcdDisplay(io_handle, panel_handle,
EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
}

void InitializeButtons() { //接入锂电池时,可长按PWR开机/关机
boot_button_.OnClick([this]() {
auto& app = Application::GetInstance();
if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
ResetWifiConfiguration();
}
});

boot_button_.OnPressDown([this]() {
Application::GetInstance().StartListening();
});

boot_button_.OnPressUp([this]() {
Application::GetInstance().StopListening();
});

pwr_button_.OnPressUp([this]() {
if(pwr_flag == 0)
{
pwr_flag = 1;
}
});
}

void InitializeTools()
{
auto& mcp_server = McpServer::GetInstance();
mcp_server.AddTool("self.disp.setbacklight", "设置屏幕亮度", PropertyList({
Property("level", kPropertyTypeInteger, 0, 255)
}), [this](const PropertyList& properties) -> ReturnValue {
int level = properties["level"].value<int>();
ESP_LOGI("setbacklight","%d",level);
SetDispbacklight(level);
return true;
});
}

void SetDispbacklight(uint8_t backlight) {
uint32_t lcd_cmd = 0x51;
lcd_cmd &= 0xff;
lcd_cmd <<= 8;
lcd_cmd |= 0x02 << 24;
uint8_t param = backlight;
esp_lcd_panel_io_tx_param(io_handle, lcd_cmd, &param,1);
}

public:
CustomBoard() :
boot_button_(BOOT_BUTTON_GPIO),pwr_button_(PWR_BUTTON_GPIO) {
InitializeI2c();
InitializeSpi();
InitializeLcdDisplay();
InitializeButtons();
InitializeTools();
}

virtual AudioCodec* GetAudioCodec() override {
static BoxAudioCodec audio_codec(
i2c_bus_,
AUDIO_INPUT_SAMPLE_RATE,
AUDIO_OUTPUT_SAMPLE_RATE,
AUDIO_I2S_GPIO_MCLK,
AUDIO_I2S_GPIO_BCLK,
AUDIO_I2S_GPIO_WS,
AUDIO_I2S_GPIO_DOUT,
AUDIO_I2S_GPIO_DIN,
AUDIO_CODEC_PA_PIN,
AUDIO_CODEC_ES8311_ADDR,
AUDIO_CODEC_ES7210_ADDR,
AUDIO_INPUT_REFERENCE);
return &audio_codec;
}

virtual Display* GetDisplay() override {
return display_;
}

};

DECLARE_BOARD(CustomBoard);