forked from espressif/esp-idf
lcd: update doc unit test and example to support 8-line spi
This commit is contained in:
@@ -63,10 +63,8 @@ extern "C"
|
|||||||
#define SPICOMMON_BUSFLAG_DUAL (1<<6) ///< Check MOSI and MISO pins can output. Or indicates bus able to work under DIO mode.
|
#define SPICOMMON_BUSFLAG_DUAL (1<<6) ///< Check MOSI and MISO pins can output. Or indicates bus able to work under DIO mode.
|
||||||
#define SPICOMMON_BUSFLAG_WPHD (1<<7) ///< Check existing of WP and HD pins. Or indicates WP & HD pins initialized.
|
#define SPICOMMON_BUSFLAG_WPHD (1<<7) ///< Check existing of WP and HD pins. Or indicates WP & HD pins initialized.
|
||||||
#define SPICOMMON_BUSFLAG_QUAD (SPICOMMON_BUSFLAG_DUAL|SPICOMMON_BUSFLAG_WPHD) ///< Check existing of MOSI/MISO/WP/HD pins as output. Or indicates bus able to work under QIO mode.
|
#define SPICOMMON_BUSFLAG_QUAD (SPICOMMON_BUSFLAG_DUAL|SPICOMMON_BUSFLAG_WPHD) ///< Check existing of MOSI/MISO/WP/HD pins as output. Or indicates bus able to work under QIO mode.
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
|
||||||
#define SPICOMMON_BUSFLAG_IO4_IO7 (1<<8) ///< Check existing of IO4~IO7 pins. Or indicates IO4~IO7 pins initialized.
|
#define SPICOMMON_BUSFLAG_IO4_IO7 (1<<8) ///< Check existing of IO4~IO7 pins. Or indicates IO4~IO7 pins initialized.
|
||||||
#define SPICOMMON_BUSFLAG_OCTAL (SPICOMMON_BUSFLAG_QUAD|SPICOMMON_BUSFLAG_IO4_IO7) ///< Check existing of MOSI/MISO/WP/HD/SPIIO4/SPIIO5/SPIIO6/SPIIO7 pins as output. Or indicates bus able to work under octal mode.
|
#define SPICOMMON_BUSFLAG_OCTAL (SPICOMMON_BUSFLAG_QUAD|SPICOMMON_BUSFLAG_IO4_IO7) ///< Check existing of MOSI/MISO/WP/HD/SPIIO4/SPIIO5/SPIIO6/SPIIO7 pins as output. Or indicates bus able to work under octal mode.
|
||||||
#endif
|
|
||||||
#define SPICOMMON_BUSFLAG_NATIVE_PINS SPICOMMON_BUSFLAG_IOMUX_PINS
|
#define SPICOMMON_BUSFLAG_NATIVE_PINS SPICOMMON_BUSFLAG_IOMUX_PINS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,12 +113,10 @@ typedef struct {
|
|||||||
int quadhd_io_num; ///< GPIO pin for HD (Hold) signal, or -1 if not used.
|
int quadhd_io_num; ///< GPIO pin for HD (Hold) signal, or -1 if not used.
|
||||||
int data3_io_num; ///< GPIO pin for spi data3 signal in quad/octal mode, or -1 if not used.
|
int data3_io_num; ///< GPIO pin for spi data3 signal in quad/octal mode, or -1 if not used.
|
||||||
};
|
};
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
|
||||||
int data4_io_num; ///< GPIO pin for spi data4 signal in octal mode, or -1 if not used.
|
int data4_io_num; ///< GPIO pin for spi data4 signal in octal mode, or -1 if not used.
|
||||||
int data5_io_num; ///< GPIO pin for spi data5 signal in octal mode, or -1 if not used.
|
int data5_io_num; ///< GPIO pin for spi data5 signal in octal mode, or -1 if not used.
|
||||||
int data6_io_num; ///< GPIO pin for spi data6 signal in octal mode, or -1 if not used.
|
int data6_io_num; ///< GPIO pin for spi data6 signal in octal mode, or -1 if not used.
|
||||||
int data7_io_num; ///< GPIO pin for spi data7 signal in octal mode, or -1 if not used.
|
int data7_io_num; ///< GPIO pin for spi data7 signal in octal mode, or -1 if not used.
|
||||||
#endif
|
|
||||||
int max_transfer_sz; ///< Maximum transfer size, in bytes. Defaults to 4092 if 0 when DMA enabled, or to `SOC_SPI_MAXIMUM_BUFFER_SIZE` if DMA is disabled.
|
int max_transfer_sz; ///< Maximum transfer size, in bytes. Defaults to 4092 if 0 when DMA enabled, or to `SOC_SPI_MAXIMUM_BUFFER_SIZE` if DMA is disabled.
|
||||||
uint32_t flags; ///< Abilities of bus to be checked by the driver. Or-ed value of ``SPICOMMON_BUSFLAG_*`` flags.
|
uint32_t flags; ///< Abilities of bus to be checked by the driver. Or-ed value of ``SPICOMMON_BUSFLAG_*`` flags.
|
||||||
int intr_flags; /**< Interrupt flag for the bus to set the priority, and IRAM attribute, see
|
int intr_flags; /**< Interrupt flag for the bus to set the priority, and IRAM attribute, see
|
||||||
|
@@ -105,11 +105,9 @@ typedef struct {
|
|||||||
#define SPI_TRANS_VARIABLE_ADDR (1<<6) ///< Use the ``address_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``.
|
#define SPI_TRANS_VARIABLE_ADDR (1<<6) ///< Use the ``address_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``.
|
||||||
#define SPI_TRANS_VARIABLE_DUMMY (1<<7) ///< Use the ``dummy_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``.
|
#define SPI_TRANS_VARIABLE_DUMMY (1<<7) ///< Use the ``dummy_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``.
|
||||||
#define SPI_TRANS_CS_KEEP_ACTIVE (1<<8) ///< Keep CS active after data transfer
|
#define SPI_TRANS_CS_KEEP_ACTIVE (1<<8) ///< Keep CS active after data transfer
|
||||||
#define MULTILINE_CMD (1<<9) ///< The number of lines transmitting command is the same as that transmitting data
|
#define SPI_TRANS_MULTILINE_CMD (1<<9) ///< The data lines used at command phase is the same as data phase (otherwise, only one data line is used at command phase)
|
||||||
#define MULTILINE_ADDR (1<<10) ///< the number of lines transmitting address is the same as that transmitting data (in dual and quad mode the same as ``SPI_TRANS_MODE_DIOQIO_ADDR``)
|
#define SPI_TRANS_MODE_OCT (1<<10) ///< Transmit/receive data in 8-bit mode
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
#define SPI_TRANS_MULTILINE_ADDR SPI_TRANS_MODE_DIOQIO_ADDR ///< The data lines used at address phase is the same as data phase (otherwise, only one data line is used at address phase)
|
||||||
#define SPI_TRANS_MODE_OCT (1<<11) ///< Transmit/receive data in 8-bit mode
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This structure describes one SPI transaction. The descriptor should not be modified until the transaction finishes.
|
* This structure describes one SPI transaction. The descriptor should not be modified until the transaction finishes.
|
||||||
@@ -153,7 +151,7 @@ typedef struct {
|
|||||||
} spi_transaction_ext_t ;
|
} spi_transaction_ext_t ;
|
||||||
|
|
||||||
|
|
||||||
typedef struct spi_device_t* spi_device_handle_t; ///< Handle for a device on a SPI bus
|
typedef struct spi_device_t *spi_device_handle_t; ///< Handle for a device on a SPI bus
|
||||||
/**
|
/**
|
||||||
* @brief Allocate a device on a SPI bus
|
* @brief Allocate a device on a SPI bus
|
||||||
*
|
*
|
||||||
@@ -346,7 +344,7 @@ void spi_device_release_bus(spi_device_handle_t dev);
|
|||||||
*
|
*
|
||||||
* @return Actual working frequency that most fit.
|
* @return Actual working frequency that most fit.
|
||||||
*/
|
*/
|
||||||
int spi_cal_clock(int fapb, int hz, int duty_cycle, uint32_t* reg_o) __attribute__((deprecated));
|
int spi_cal_clock(int fapb, int hz, int duty_cycle, uint32_t *reg_o) __attribute__((deprecated));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculate the working frequency that is most close to desired frequency.
|
* @brief Calculate the working frequency that is most close to desired frequency.
|
||||||
@@ -373,7 +371,7 @@ int spi_get_actual_clock(int fapb, int hz, int duty_cycle);
|
|||||||
*
|
*
|
||||||
* @note If **dummy_o* is not zero, it means dummy bits should be applied in half duplex mode, and full duplex mode may not work.
|
* @note If **dummy_o* is not zero, it means dummy bits should be applied in half duplex mode, and full duplex mode may not work.
|
||||||
*/
|
*/
|
||||||
void spi_get_timing(bool gpio_is_used, int input_delay_ns, int eff_clk, int* dummy_o, int* cycles_remain_o);
|
void spi_get_timing(bool gpio_is_used, int input_delay_ns, int eff_clk, int *dummy_o, int *cycles_remain_o);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the frequency limit of current configurations.
|
* @brief Get the frequency limit of current configurations.
|
||||||
|
@@ -354,6 +354,9 @@ esp_err_t spicommon_slave_free_dma(spi_host_device_t host_id)
|
|||||||
#if SOC_SPI_SUPPORT_OCT
|
#if SOC_SPI_SUPPORT_OCT
|
||||||
static bool check_iomux_pins_oct(spi_host_device_t host, const spi_bus_config_t* bus_config)
|
static bool check_iomux_pins_oct(spi_host_device_t host, const spi_bus_config_t* bus_config)
|
||||||
{
|
{
|
||||||
|
if (host != SPI2_HOST) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
int io_nums[] = {bus_config->data0_io_num, bus_config->data1_io_num, bus_config->data2_io_num, bus_config->data3_io_num,
|
int io_nums[] = {bus_config->data0_io_num, bus_config->data1_io_num, bus_config->data2_io_num, bus_config->data3_io_num,
|
||||||
bus_config->sclk_io_num, bus_config->data4_io_num, bus_config->data5_io_num, bus_config->data6_io_num, bus_config->data7_io_num};
|
bus_config->sclk_io_num, bus_config->data4_io_num, bus_config->data5_io_num, bus_config->data6_io_num, bus_config->data7_io_num};
|
||||||
int io_mux_nums[] = {SPI2_IOMUX_PIN_NUM_MOSI_OCT, SPI2_IOMUX_PIN_NUM_MISO_OCT, SPI2_IOMUX_PIN_NUM_WP_OCT, SPI2_IOMUX_PIN_NUM_HD_OCT,
|
int io_mux_nums[] = {SPI2_IOMUX_PIN_NUM_MOSI_OCT, SPI2_IOMUX_PIN_NUM_MISO_OCT, SPI2_IOMUX_PIN_NUM_WP_OCT, SPI2_IOMUX_PIN_NUM_HD_OCT,
|
||||||
|
@@ -532,16 +532,15 @@ static void SPI_MASTER_ISR_ATTR spi_new_trans(spi_device_t *dev, spi_trans_priv_
|
|||||||
hal_trans.cs_keep_active = (trans->flags & SPI_TRANS_CS_KEEP_ACTIVE) ? 1 : 0;
|
hal_trans.cs_keep_active = (trans->flags & SPI_TRANS_CS_KEEP_ACTIVE) ? 1 : 0;
|
||||||
|
|
||||||
//Set up OIO/QIO/DIO if needed
|
//Set up OIO/QIO/DIO if needed
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
|
||||||
hal_trans.line_mode.data_lines = (trans->flags & SPI_TRANS_MODE_DIO) ? 2 :
|
|
||||||
(trans->flags & SPI_TRANS_MODE_QIO) ? 4 :
|
|
||||||
(trans->flags & SPI_TRANS_MODE_OCT) ? 8 : 1;
|
|
||||||
#else
|
|
||||||
hal_trans.line_mode.data_lines = (trans->flags & SPI_TRANS_MODE_DIO) ? 2 :
|
hal_trans.line_mode.data_lines = (trans->flags & SPI_TRANS_MODE_DIO) ? 2 :
|
||||||
(trans->flags & SPI_TRANS_MODE_QIO) ? 4 : 1;
|
(trans->flags & SPI_TRANS_MODE_QIO) ? 4 : 1;
|
||||||
|
#if SOC_SPI_SUPPORT_OCT
|
||||||
|
if (trans->flags & SPI_TRANS_MODE_OCT) {
|
||||||
|
hal_trans.line_mode.data_lines = 8;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
hal_trans.line_mode.addr_lines = (trans->flags & (SPI_TRANS_MODE_DIOQIO_ADDR | MULTILINE_ADDR)) ? hal_trans.line_mode.data_lines : 1;
|
hal_trans.line_mode.addr_lines = (trans->flags & SPI_TRANS_MULTILINE_ADDR) ? hal_trans.line_mode.data_lines : 1;
|
||||||
hal_trans.line_mode.cmd_lines = (trans->flags & MULTILINE_CMD) ? hal_trans.line_mode.data_lines : 1;
|
hal_trans.line_mode.cmd_lines = (trans->flags & SPI_TRANS_MULTILINE_CMD) ? hal_trans.line_mode.data_lines : 1;
|
||||||
|
|
||||||
if (trans->flags & SPI_TRANS_VARIABLE_CMD) {
|
if (trans->flags & SPI_TRANS_VARIABLE_CMD) {
|
||||||
hal_trans.cmd_bits = ((spi_transaction_ext_t *)trans)->command_bits;
|
hal_trans.cmd_bits = ((spi_transaction_ext_t *)trans)->command_bits;
|
||||||
@@ -693,11 +692,11 @@ static SPI_MASTER_ISR_ATTR esp_err_t check_trans_valid(spi_device_handle_t handl
|
|||||||
//check working mode
|
//check working mode
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
#if SOC_SPI_SUPPORT_OCT
|
||||||
SPI_CHECK(!(host->id == SPI3_HOST && trans_desc->flags & SPI_TRANS_MODE_OCT), "SPI3 does not support octal mode", ESP_ERR_INVALID_ARG);
|
SPI_CHECK(!(host->id == SPI3_HOST && trans_desc->flags & SPI_TRANS_MODE_OCT), "SPI3 does not support octal mode", ESP_ERR_INVALID_ARG);
|
||||||
SPI_CHECK(!((trans_desc->flags & SPI_TRANS_MODE_OCT) && (handle->cfg.flags & SPI_DEVICE_3WIRE)), "incompatible interface parameters", ESP_ERR_INVALID_ARG);
|
SPI_CHECK(!((trans_desc->flags & SPI_TRANS_MODE_OCT) && (handle->cfg.flags & SPI_DEVICE_3WIRE)), "Incompatible when setting to both Octal mode and 3-wire-mode", ESP_ERR_INVALID_ARG);
|
||||||
SPI_CHECK(!((trans_desc->flags & SPI_TRANS_MODE_OCT) && !is_half_duplex), "incompatible interface parameters", ESP_ERR_INVALID_ARG);
|
SPI_CHECK(!((trans_desc->flags & SPI_TRANS_MODE_OCT) && !is_half_duplex), "Incompatible when setting to both Octal mode and half duplex mode", ESP_ERR_INVALID_ARG);
|
||||||
#endif
|
#endif
|
||||||
SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && (handle->cfg.flags & SPI_DEVICE_3WIRE)), "incompatible interface parameters", ESP_ERR_INVALID_ARG);
|
SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && (handle->cfg.flags & SPI_DEVICE_3WIRE)), "Incompatible when setting to both multi-line mode and 3-wire-mode", ESP_ERR_INVALID_ARG);
|
||||||
SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && !is_half_duplex), "incompatible interface parameters", ESP_ERR_INVALID_ARG);
|
SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && !is_half_duplex), "Incompatible when setting to both multi-line mode and half duplex mode", ESP_ERR_INVALID_ARG);
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||||
SPI_CHECK(!is_half_duplex || !bus_attr->dma_enabled || !rx_enabled || !tx_enabled, "SPI half duplex mode does not support using DMA with both MOSI and MISO phases.", ESP_ERR_INVALID_ARG );
|
SPI_CHECK(!is_half_duplex || !bus_attr->dma_enabled || !rx_enabled || !tx_enabled, "SPI half duplex mode does not support using DMA with both MOSI and MISO phases.", ESP_ERR_INVALID_ARG );
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
@@ -61,9 +61,7 @@ esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_p
|
|||||||
ESP_GOTO_ON_FALSE(spi_panel_io, ESP_ERR_NO_MEM, err, TAG, "no mem for spi panel io");
|
ESP_GOTO_ON_FALSE(spi_panel_io, ESP_ERR_NO_MEM, err, TAG, "no mem for spi panel io");
|
||||||
|
|
||||||
spi_device_interface_config_t devcfg = {
|
spi_device_interface_config_t devcfg = {
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
.flags = io_config->flags.octal_mode ? SPI_DEVICE_HALFDUPLEX : 0,
|
||||||
.flags = SPI_DEVICE_HALFDUPLEX, // lcd driver only use one transfer direction, so half duplex is enough.
|
|
||||||
#endif
|
|
||||||
.clock_speed_hz = io_config->pclk_hz,
|
.clock_speed_hz = io_config->pclk_hz,
|
||||||
.mode = io_config->spi_mode,
|
.mode = io_config->spi_mode,
|
||||||
.spics_io_num = io_config->cs_gpio_num,
|
.spics_io_num = io_config->cs_gpio_num,
|
||||||
@@ -152,11 +150,10 @@ static esp_err_t panel_io_spi_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||||||
lcd_trans->flags.dc_gpio_level = !spi_panel_io->flags.dc_data_level; // set D/C line to command mode
|
lcd_trans->flags.dc_gpio_level = !spi_panel_io->flags.dc_data_level; // set D/C line to command mode
|
||||||
lcd_trans->base.length = spi_panel_io->lcd_cmd_bits;
|
lcd_trans->base.length = spi_panel_io->lcd_cmd_bits;
|
||||||
lcd_trans->base.tx_buffer = &lcd_cmd;
|
lcd_trans->base.tx_buffer = &lcd_cmd;
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
|
||||||
if (spi_panel_io->flags.octal_mode) {
|
if (spi_panel_io->flags.octal_mode) {
|
||||||
lcd_trans->base.flags |= (MULTILINE_CMD | MULTILINE_ADDR | SPI_TRANS_MODE_OCT);
|
// use 8 lines for transmitting command, address and data
|
||||||
|
lcd_trans->base.flags |= (SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR | SPI_TRANS_MODE_OCT);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (spi_panel_io->flags.dc_as_cmd_phase) { // encoding DC value to SPI command phase when necessary
|
if (spi_panel_io->flags.dc_as_cmd_phase) { // encoding DC value to SPI command phase when necessary
|
||||||
lcd_trans->base.cmd = !spi_panel_io->flags.dc_data_level;
|
lcd_trans->base.cmd = !spi_panel_io->flags.dc_data_level;
|
||||||
}
|
}
|
||||||
@@ -202,11 +199,10 @@ static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||||||
if (spi_panel_io->flags.dc_as_cmd_phase) { // encoding DC value to SPI command phase when necessary
|
if (spi_panel_io->flags.dc_as_cmd_phase) { // encoding DC value to SPI command phase when necessary
|
||||||
lcd_trans->base.cmd = !spi_panel_io->flags.dc_data_level;
|
lcd_trans->base.cmd = !spi_panel_io->flags.dc_data_level;
|
||||||
}
|
}
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
|
||||||
if (spi_panel_io->flags.octal_mode) {
|
if (spi_panel_io->flags.octal_mode) {
|
||||||
lcd_trans->base.flags |= (MULTILINE_CMD | MULTILINE_ADDR | SPI_TRANS_MODE_OCT);
|
// use 8 lines for transmitting command, address and data
|
||||||
|
lcd_trans->base.flags |= (SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR | SPI_TRANS_MODE_OCT);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
// command is short, using polling mode
|
// command is short, using polling mode
|
||||||
ret = spi_device_polling_transmit(spi_panel_io->spi_dev, &lcd_trans->base);
|
ret = spi_device_polling_transmit(spi_panel_io->spi_dev, &lcd_trans->base);
|
||||||
ESP_GOTO_ON_ERROR(ret, err, TAG, "spi transmit (polling) command failed");
|
ESP_GOTO_ON_ERROR(ret, err, TAG, "spi transmit (polling) command failed");
|
||||||
|
18
components/esp_lcd/test/test_spi_board.h
Normal file
18
components/esp_lcd/test/test_spi_board.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#define TEST_LCD_H_RES (240)
|
||||||
|
#define TEST_LCD_V_RES (280)
|
||||||
|
|
||||||
|
#define TEST_LCD_BK_LIGHT_GPIO (18)
|
||||||
|
#define TEST_LCD_RST_GPIO (5)
|
||||||
|
#define TEST_LCD_CS_GPIO (0)
|
||||||
|
#define TEST_LCD_DC_GPIO (19)
|
||||||
|
#define TEST_LCD_PCLK_GPIO (2)
|
||||||
|
#define TEST_LCD_DATA0_GPIO (4)
|
||||||
|
#define TEST_LCD_DATA1_GPIO (7)
|
||||||
|
#define TEST_LCD_DATA2_GPIO (8)
|
||||||
|
#define TEST_LCD_DATA3_GPIO (9)
|
||||||
|
#define TEST_LCD_DATA4_GPIO (10)
|
||||||
|
#define TEST_LCD_DATA5_GPIO (11)
|
||||||
|
#define TEST_LCD_DATA6_GPIO (12)
|
||||||
|
#define TEST_LCD_DATA7_GPIO (13)
|
@@ -9,29 +9,15 @@
|
|||||||
#include "esp_lcd_panel_vendor.h"
|
#include "esp_lcd_panel_vendor.h"
|
||||||
#include "esp_lcd_panel_ops.h"
|
#include "esp_lcd_panel_ops.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
#include "test_spi_board.h"
|
||||||
|
|
||||||
#define TEST_LCD_H_RES (240)
|
|
||||||
#define TEST_LCD_V_RES (280)
|
|
||||||
#define TEST_LCD_CLK_GPIO (2)
|
|
||||||
#define TEST_LCD_DATA0_GPIO (4)
|
|
||||||
#define TEST_LCD_RST_GPIO (5)
|
|
||||||
#define TEST_LCD_DC_GPIO (18)
|
|
||||||
#define TEST_LCD_BK_LIGHT_GPIO (19)
|
|
||||||
#define TEST_LCD_CS_GPIO (0)
|
|
||||||
#define TEST_LCD_DATA1_GPIO (7)
|
|
||||||
#define TEST_LCD_DATA2_GPIO (8)
|
|
||||||
#define TEST_LCD_DATA3_GPIO (9)
|
|
||||||
#define TEST_LCD_DATA4_GPIO (10)
|
|
||||||
#define TEST_LCD_DATA5_GPIO (11)
|
|
||||||
#define TEST_LCD_DATA6_GPIO (12)
|
|
||||||
#define TEST_LCD_DATA7_GPIO (13)
|
|
||||||
#define TEST_SPI_HOST_ID (1)
|
#define TEST_SPI_HOST_ID (1)
|
||||||
#define TEST_LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000)
|
#define TEST_LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000) // 20MHz
|
||||||
|
|
||||||
typedef bool (*trans_done_callback)(esp_lcd_panel_io_handle_t, void *, void *);
|
typedef bool (*trans_done_callback_t)(esp_lcd_panel_io_handle_t, void *, void *);
|
||||||
|
|
||||||
static void lcd_initialize(bool is_8_line_lcd, esp_lcd_panel_io_handle_t *io_handle, esp_lcd_panel_handle_t *panel_handle,
|
static void lcd_initialize_spi(esp_lcd_panel_io_handle_t *io_handle, esp_lcd_panel_handle_t *panel_handle, trans_done_callback_t on_color_trans_done, void *user_data, bool oct_mode)
|
||||||
int spi_mode, trans_done_callback on_color_trans_done, void *user_data)
|
|
||||||
{
|
{
|
||||||
gpio_config_t bk_gpio_config = {
|
gpio_config_t bk_gpio_config = {
|
||||||
.mode = GPIO_MODE_OUTPUT,
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
@@ -40,15 +26,14 @@ static void lcd_initialize(bool is_8_line_lcd, esp_lcd_panel_io_handle_t *io_han
|
|||||||
TEST_ESP_OK(gpio_config(&bk_gpio_config));
|
TEST_ESP_OK(gpio_config(&bk_gpio_config));
|
||||||
|
|
||||||
spi_bus_config_t buscfg = {
|
spi_bus_config_t buscfg = {
|
||||||
.miso_io_num = -1,
|
.sclk_io_num = TEST_LCD_PCLK_GPIO,
|
||||||
.mosi_io_num = TEST_LCD_DATA0_GPIO,
|
.mosi_io_num = TEST_LCD_DATA0_GPIO,
|
||||||
.sclk_io_num = TEST_LCD_CLK_GPIO,
|
.miso_io_num = -1,
|
||||||
.quadwp_io_num = -1,
|
.quadwp_io_num = -1,
|
||||||
.quadhd_io_num = -1,
|
.quadhd_io_num = -1,
|
||||||
.max_transfer_sz = TEST_LCD_H_RES * TEST_LCD_V_RES * sizeof(uint16_t)
|
.max_transfer_sz = TEST_LCD_H_RES * TEST_LCD_V_RES * sizeof(uint16_t)
|
||||||
};
|
};
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
if (oct_mode) {
|
||||||
if (is_8_line_lcd) {
|
|
||||||
buscfg.data1_io_num = TEST_LCD_DATA1_GPIO;
|
buscfg.data1_io_num = TEST_LCD_DATA1_GPIO;
|
||||||
buscfg.data2_io_num = TEST_LCD_DATA2_GPIO;
|
buscfg.data2_io_num = TEST_LCD_DATA2_GPIO;
|
||||||
buscfg.data3_io_num = TEST_LCD_DATA3_GPIO;
|
buscfg.data3_io_num = TEST_LCD_DATA3_GPIO;
|
||||||
@@ -58,25 +43,23 @@ static void lcd_initialize(bool is_8_line_lcd, esp_lcd_panel_io_handle_t *io_han
|
|||||||
buscfg.data7_io_num = TEST_LCD_DATA7_GPIO;
|
buscfg.data7_io_num = TEST_LCD_DATA7_GPIO;
|
||||||
buscfg.flags = SPICOMMON_BUSFLAG_OCTAL;
|
buscfg.flags = SPICOMMON_BUSFLAG_OCTAL;
|
||||||
}
|
}
|
||||||
#endif //SOC_SPI_SUPPORT_OCT
|
|
||||||
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST_ID, &buscfg, SPI_DMA_CH_AUTO));
|
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST_ID, &buscfg, SPI_DMA_CH_AUTO));
|
||||||
|
|
||||||
esp_lcd_panel_io_spi_config_t io_config = {
|
esp_lcd_panel_io_spi_config_t io_config = {
|
||||||
.dc_gpio_num = TEST_LCD_DC_GPIO,
|
.dc_gpio_num = TEST_LCD_DC_GPIO,
|
||||||
.cs_gpio_num = TEST_LCD_CS_GPIO,
|
.cs_gpio_num = TEST_LCD_CS_GPIO,
|
||||||
.pclk_hz = TEST_LCD_PIXEL_CLOCK_HZ,
|
.pclk_hz = TEST_LCD_PIXEL_CLOCK_HZ,
|
||||||
.spi_mode = spi_mode,
|
.spi_mode = 0,
|
||||||
.trans_queue_depth = 10,
|
.trans_queue_depth = 10,
|
||||||
.lcd_cmd_bits = 8,
|
.lcd_cmd_bits = 8,
|
||||||
.lcd_param_bits = 8,
|
.lcd_param_bits = 8,
|
||||||
.on_color_trans_done = on_color_trans_done,
|
.on_color_trans_done = on_color_trans_done,
|
||||||
.user_data = user_data
|
.user_data = user_data
|
||||||
};
|
};
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
if (oct_mode) {
|
||||||
if (is_8_line_lcd) {
|
|
||||||
io_config.flags.octal_mode = 1;
|
io_config.flags.octal_mode = 1;
|
||||||
|
io_config.spi_mode = 3;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
TEST_ESP_OK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)TEST_SPI_HOST_ID, &io_config, io_handle));
|
TEST_ESP_OK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)TEST_SPI_HOST_ID, &io_config, io_handle));
|
||||||
|
|
||||||
esp_lcd_panel_dev_config_t panel_config = {
|
esp_lcd_panel_dev_config_t panel_config = {
|
||||||
@@ -125,7 +108,7 @@ TEST_CASE("lcd panel with 8-line spi interface (st7789)", "[lcd]")
|
|||||||
{
|
{
|
||||||
esp_lcd_panel_io_handle_t io_handle = NULL;
|
esp_lcd_panel_io_handle_t io_handle = NULL;
|
||||||
esp_lcd_panel_handle_t panel_handle = NULL;
|
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||||
lcd_initialize(true, &io_handle, &panel_handle, 3, NULL, NULL);
|
lcd_initialize_spi(&io_handle, &panel_handle, NULL, NULL, true);
|
||||||
lcd_panel_test(io_handle, panel_handle);
|
lcd_panel_test(io_handle, panel_handle);
|
||||||
}
|
}
|
||||||
#endif // SOC_SPI_SUPPORT_OCT
|
#endif // SOC_SPI_SUPPORT_OCT
|
||||||
@@ -134,7 +117,7 @@ TEST_CASE("lcd panel with 1-line spi interface (st7789)", "[lcd]")
|
|||||||
{
|
{
|
||||||
esp_lcd_panel_io_handle_t io_handle = NULL;
|
esp_lcd_panel_io_handle_t io_handle = NULL;
|
||||||
esp_lcd_panel_handle_t panel_handle = NULL;
|
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||||
lcd_initialize(false, &io_handle, &panel_handle, 0, NULL, NULL);
|
lcd_initialize_spi(&io_handle, &panel_handle, NULL, NULL, false);
|
||||||
lcd_panel_test(io_handle, panel_handle);
|
lcd_panel_test(io_handle, panel_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,13 +149,14 @@ static void lvgl_gui_test(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_han
|
|||||||
|
|
||||||
test_lvgl_task_loop(panel_handle, TEST_LCD_H_RES, TEST_LCD_V_RES, disp);
|
test_lvgl_task_loop(panel_handle, TEST_LCD_H_RES, TEST_LCD_V_RES, disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOC_SPI_SUPPORT_OCT
|
#if SOC_SPI_SUPPORT_OCT
|
||||||
TEST_CASE("lvgl gui with 8-line spi interface (st7789)", "[lcd][lvgl][ignore]")
|
TEST_CASE("lvgl gui with 8-line spi interface (st7789)", "[lcd][lvgl][ignore]")
|
||||||
{
|
{
|
||||||
lv_disp_t *disp = NULL;
|
lv_disp_t *disp = NULL;
|
||||||
esp_lcd_panel_io_handle_t io_handle = NULL;
|
esp_lcd_panel_io_handle_t io_handle = NULL;
|
||||||
esp_lcd_panel_handle_t panel_handle = NULL;
|
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||||
lcd_initialize(true, &io_handle, &panel_handle, 3, notify_lvgl_ready_to_flush, &disp);
|
lcd_initialize_spi(&io_handle, &panel_handle, notify_lvgl_ready_to_flush, &disp, true);
|
||||||
|
|
||||||
lvgl_gui_test(io_handle, panel_handle, &disp);
|
lvgl_gui_test(io_handle, panel_handle, &disp);
|
||||||
}
|
}
|
||||||
@@ -183,7 +167,7 @@ TEST_CASE("lvgl gui with 1-line spi interface (st7789)", "[lcd][lvgl][ignore]")
|
|||||||
lv_disp_t *disp = NULL;
|
lv_disp_t *disp = NULL;
|
||||||
esp_lcd_panel_io_handle_t io_handle = NULL;
|
esp_lcd_panel_io_handle_t io_handle = NULL;
|
||||||
esp_lcd_panel_handle_t panel_handle = NULL;
|
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||||
lcd_initialize(false, &io_handle, &panel_handle, 0, notify_lvgl_ready_to_flush, &disp);
|
lcd_initialize_spi(&io_handle, &panel_handle, notify_lvgl_ready_to_flush, &disp, false);
|
||||||
|
|
||||||
lvgl_gui_test(io_handle, panel_handle, &disp);
|
lvgl_gui_test(io_handle, panel_handle, &disp);
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "soc/spi_periph.h"
|
#include "soc/spi_periph.h"
|
||||||
#include "hal/misc.h"
|
#include "hal/misc.h"
|
||||||
#include "hal/spi_types.h"
|
#include "hal/spi_types.h"
|
||||||
|
#include "hal/assert.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -453,40 +454,40 @@ static inline void spi_ll_master_set_line_mode(spi_dev_t *hw, spi_line_mode_t li
|
|||||||
hw->ctrl.val &= ~SPI_LL_ONE_LINE_CTRL_MASK;
|
hw->ctrl.val &= ~SPI_LL_ONE_LINE_CTRL_MASK;
|
||||||
hw->user.val &= ~SPI_LL_ONE_LINE_USER_MASK;
|
hw->user.val &= ~SPI_LL_ONE_LINE_USER_MASK;
|
||||||
if (line_mode.cmd_lines > 1) {
|
if (line_mode.cmd_lines > 1) {
|
||||||
abort();
|
HAL_ASSERT(false);
|
||||||
}
|
}
|
||||||
switch (line_mode.data_lines) {
|
switch (line_mode.data_lines) {
|
||||||
case 2:
|
case 2:
|
||||||
if (line_mode.addr_lines == 1) {
|
if (line_mode.addr_lines == 1) {
|
||||||
// 1-line-cmd + 1-line-addr + 2-line-data
|
// 1-line-cmd + 1-line-addr + 2-line-data
|
||||||
hw->ctrl.fread_dual = 1;
|
hw->ctrl.fread_dual = 1;
|
||||||
hw->user.fwrite_dual = 1;
|
hw->user.fwrite_dual = 1;
|
||||||
} else if (line_mode.addr_lines == 2) {
|
} else if (line_mode.addr_lines == 2) {
|
||||||
// 1-line-cmd + 2-line-addr + 2-line-data
|
// 1-line-cmd + 2-line-addr + 2-line-data
|
||||||
hw->ctrl.fread_dio = 1;
|
hw->ctrl.fread_dio = 1;
|
||||||
hw->user.fwrite_dio = 1;
|
hw->user.fwrite_dio = 1;
|
||||||
} else {
|
} else {
|
||||||
abort();
|
HAL_ASSERT(false);
|
||||||
}
|
}
|
||||||
hw->ctrl.fastrd_mode = 1;
|
hw->ctrl.fastrd_mode = 1;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (line_mode.addr_lines == 1) {
|
if (line_mode.addr_lines == 1) {
|
||||||
// 1-line-cmd + 1-line-addr + 4-line-data
|
// 1-line-cmd + 1-line-addr + 4-line-data
|
||||||
hw->ctrl.fread_quad = 1;
|
hw->ctrl.fread_quad = 1;
|
||||||
hw->user.fwrite_quad = 1;
|
hw->user.fwrite_quad = 1;
|
||||||
} else if (line_mode.addr_lines == 4) {
|
} else if (line_mode.addr_lines == 4) {
|
||||||
// 1-line-cmd + 4-line-addr + 4-line-data
|
// 1-line-cmd + 4-line-addr + 4-line-data
|
||||||
hw->ctrl.fread_qio = 1;
|
hw->ctrl.fread_qio = 1;
|
||||||
hw->user.fwrite_qio = 1;
|
hw->user.fwrite_qio = 1;
|
||||||
} else {
|
} else {
|
||||||
abort();
|
HAL_ASSERT(false);
|
||||||
}
|
}
|
||||||
hw->ctrl.fastrd_mode = 1;
|
hw->ctrl.fastrd_mode = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// 1-line-cmd + 1-line-addr + 1-line-data
|
// 1-line-cmd + 1-line-addr + 1-line-data
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,7 +510,8 @@ static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id)
|
|||||||
* @param hw Beginning address of the peripheral registers.
|
* @param hw Beginning address of the peripheral registers.
|
||||||
* @param keep_active if 0 don't keep CS activated, else keep CS activated
|
* @param keep_active if 0 don't keep CS activated, else keep CS activated
|
||||||
*/
|
*/
|
||||||
static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active) {
|
static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||||
|
{
|
||||||
hw->pin.cs_keep_active = (keep_active != 0) ? 1 : 0;
|
hw->pin.cs_keep_active = (keep_active != 0) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -349,7 +349,7 @@ static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_s
|
|||||||
*/
|
*/
|
||||||
static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *data, int len)
|
static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
HAL_ASSERT(byte_id+len <= 64);
|
HAL_ASSERT(byte_id + len <= 64);
|
||||||
HAL_ASSERT(len > 0);
|
HAL_ASSERT(len > 0);
|
||||||
HAL_ASSERT(byte_id >= 0);
|
HAL_ASSERT(byte_id >= 0);
|
||||||
|
|
||||||
@@ -357,10 +357,14 @@ static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t
|
|||||||
uint32_t word;
|
uint32_t word;
|
||||||
int offset = byte_id % 4;
|
int offset = byte_id % 4;
|
||||||
int copy_len = 4 - offset;
|
int copy_len = 4 - offset;
|
||||||
if (copy_len > len) copy_len = len;
|
if (copy_len > len) {
|
||||||
|
copy_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
//read-modify-write
|
//read-modify-write
|
||||||
if (copy_len != 4) word = hw->data_buf[byte_id / 4]; //read
|
if (copy_len != 4) {
|
||||||
|
word = hw->data_buf[byte_id / 4]; //read
|
||||||
|
}
|
||||||
memcpy(((uint8_t *)&word) + offset, data, copy_len); //modify
|
memcpy(((uint8_t *)&word) + offset, data, copy_len); //modify
|
||||||
hw->data_buf[byte_id / 4] = word; //write
|
hw->data_buf[byte_id / 4] = word; //write
|
||||||
|
|
||||||
@@ -404,7 +408,9 @@ static inline void spi_ll_read_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *
|
|||||||
uint32_t word = hw->data_buf[byte_id / 4];
|
uint32_t word = hw->data_buf[byte_id / 4];
|
||||||
int offset = byte_id % 4;
|
int offset = byte_id % 4;
|
||||||
int copy_len = 4 - offset;
|
int copy_len = 4 - offset;
|
||||||
if (copy_len > len) copy_len = len;
|
if (copy_len > len) {
|
||||||
|
copy_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(out_data, ((uint8_t *)&word) + offset, copy_len);
|
memcpy(out_data, ((uint8_t *)&word) + offset, copy_len);
|
||||||
byte_id += copy_len;
|
byte_id += copy_len;
|
||||||
@@ -587,7 +593,8 @@ static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id)
|
|||||||
* @param hw Beginning address of the peripheral registers.
|
* @param hw Beginning address of the peripheral registers.
|
||||||
* @param keep_active if 0 don't keep CS activated, else keep CS activated
|
* @param keep_active if 0 don't keep CS activated, else keep CS activated
|
||||||
*/
|
*/
|
||||||
static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active) {
|
static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||||
|
{
|
||||||
hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0;
|
hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -971,35 +978,35 @@ static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw)
|
|||||||
item(SPI_LL_INTR_CMDA, dma_int_ena.cmda, dma_int_raw.cmda, dma_int_clr.cmda=1)
|
item(SPI_LL_INTR_CMDA, dma_int_ena.cmda, dma_int_raw.cmda, dma_int_clr.cmda=1)
|
||||||
|
|
||||||
|
|
||||||
static inline void spi_ll_enable_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1;
|
#define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1;
|
||||||
FOR_EACH_ITEM(ENA_INTR, INTR_LIST);
|
FOR_EACH_ITEM(ENA_INTR, INTR_LIST);
|
||||||
#undef ENA_INTR
|
#undef ENA_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_disable_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_disable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0;
|
#define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0;
|
||||||
FOR_EACH_ITEM(DIS_INTR, INTR_LIST);
|
FOR_EACH_ITEM(DIS_INTR, INTR_LIST);
|
||||||
#undef DIS_INTR
|
#undef DIS_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_set_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_set_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define SET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit)) hw->st_reg = 1;
|
#define SET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit)) hw->st_reg = 1;
|
||||||
FOR_EACH_ITEM(SET_INTR, INTR_LIST);
|
FOR_EACH_ITEM(SET_INTR, INTR_LIST);
|
||||||
#undef SET_INTR
|
#undef SET_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_clear_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_clear_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define CLR_INTR(intr_bit, _, __, clr_reg) if (intr_mask & (intr_bit)) hw->clr_reg;
|
#define CLR_INTR(intr_bit, _, __, clr_reg) if (intr_mask & (intr_bit)) hw->clr_reg;
|
||||||
FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
|
FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
|
||||||
#undef CLR_INTR
|
#undef CLR_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool spi_ll_get_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline bool spi_ll_get_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define GET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit) && hw->st_reg) return true;
|
#define GET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit) && hw->st_reg) return true;
|
||||||
FOR_EACH_ITEM(GET_INTR, INTR_LIST);
|
FOR_EACH_ITEM(GET_INTR, INTR_LIST);
|
||||||
@@ -1053,7 +1060,7 @@ static inline void spi_ll_enable_int(spi_dev_t *hw)
|
|||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Slave HD
|
* Slave HD
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t* hw, spi_ll_trans_len_cond_t cond_mask)
|
static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t *hw, spi_ll_trans_len_cond_t cond_mask)
|
||||||
{
|
{
|
||||||
hw->slave.rdbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
|
hw->slave.rdbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
|
||||||
hw->slave.wrbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
|
hw->slave.wrbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
|
||||||
@@ -1061,12 +1068,12 @@ static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t* hw, spi_ll_trans_len_
|
|||||||
hw->slave.wrdma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0;
|
hw->slave.wrdma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t* hw)
|
static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t *hw)
|
||||||
{
|
{
|
||||||
return hw->slave1.data_bitlen / 8;
|
return hw->slave1.data_bitlen / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t* hw)
|
static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
|
||||||
{
|
{
|
||||||
return hw->slave1.last_addr;
|
return hw->slave1.last_addr;
|
||||||
}
|
}
|
||||||
|
@@ -347,7 +347,7 @@ static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_s
|
|||||||
*/
|
*/
|
||||||
static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *data, int len)
|
static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
HAL_ASSERT(byte_id+len <= 64);
|
HAL_ASSERT(byte_id + len <= 64);
|
||||||
HAL_ASSERT(len > 0);
|
HAL_ASSERT(len > 0);
|
||||||
HAL_ASSERT(byte_id >= 0);
|
HAL_ASSERT(byte_id >= 0);
|
||||||
|
|
||||||
@@ -355,10 +355,14 @@ static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t
|
|||||||
uint32_t word;
|
uint32_t word;
|
||||||
int offset = byte_id % 4;
|
int offset = byte_id % 4;
|
||||||
int copy_len = 4 - offset;
|
int copy_len = 4 - offset;
|
||||||
if (copy_len > len) copy_len = len;
|
if (copy_len > len) {
|
||||||
|
copy_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
//read-modify-write
|
//read-modify-write
|
||||||
if (copy_len != 4) word = hw->data_buf[byte_id / 4]; //read
|
if (copy_len != 4) {
|
||||||
|
word = hw->data_buf[byte_id / 4]; //read
|
||||||
|
}
|
||||||
memcpy(((uint8_t *)&word) + offset, data, copy_len); //modify
|
memcpy(((uint8_t *)&word) + offset, data, copy_len); //modify
|
||||||
hw->data_buf[byte_id / 4] = word; //write
|
hw->data_buf[byte_id / 4] = word; //write
|
||||||
|
|
||||||
@@ -402,7 +406,9 @@ static inline void spi_ll_read_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *
|
|||||||
uint32_t word = hw->data_buf[byte_id / 4];
|
uint32_t word = hw->data_buf[byte_id / 4];
|
||||||
int offset = byte_id % 4;
|
int offset = byte_id % 4;
|
||||||
int copy_len = 4 - offset;
|
int copy_len = 4 - offset;
|
||||||
if (copy_len > len) copy_len = len;
|
if (copy_len > len) {
|
||||||
|
copy_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(out_data, ((uint8_t *)&word) + offset, copy_len);
|
memcpy(out_data, ((uint8_t *)&word) + offset, copy_len);
|
||||||
byte_id += copy_len;
|
byte_id += copy_len;
|
||||||
@@ -586,7 +592,8 @@ static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id)
|
|||||||
* @param hw Beginning address of the peripheral registers.
|
* @param hw Beginning address of the peripheral registers.
|
||||||
* @param keep_active if 0 don't keep CS activated, else keep CS activated
|
* @param keep_active if 0 don't keep CS activated, else keep CS activated
|
||||||
*/
|
*/
|
||||||
static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active) {
|
static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||||
|
{
|
||||||
hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0;
|
hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -970,35 +977,35 @@ static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw)
|
|||||||
item(SPI_LL_INTR_CMDA, dma_int_ena.cmda, dma_int_raw.cmda, dma_int_clr.cmda=1)
|
item(SPI_LL_INTR_CMDA, dma_int_ena.cmda, dma_int_raw.cmda, dma_int_clr.cmda=1)
|
||||||
|
|
||||||
|
|
||||||
static inline void spi_ll_enable_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1;
|
#define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1;
|
||||||
FOR_EACH_ITEM(ENA_INTR, INTR_LIST);
|
FOR_EACH_ITEM(ENA_INTR, INTR_LIST);
|
||||||
#undef ENA_INTR
|
#undef ENA_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_disable_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_disable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0;
|
#define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0;
|
||||||
FOR_EACH_ITEM(DIS_INTR, INTR_LIST);
|
FOR_EACH_ITEM(DIS_INTR, INTR_LIST);
|
||||||
#undef DIS_INTR
|
#undef DIS_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_set_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_set_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define SET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit)) hw->st_reg = 1;
|
#define SET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit)) hw->st_reg = 1;
|
||||||
FOR_EACH_ITEM(SET_INTR, INTR_LIST);
|
FOR_EACH_ITEM(SET_INTR, INTR_LIST);
|
||||||
#undef SET_INTR
|
#undef SET_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_clear_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_clear_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define CLR_INTR(intr_bit, _, __, clr_reg) if (intr_mask & (intr_bit)) hw->clr_reg;
|
#define CLR_INTR(intr_bit, _, __, clr_reg) if (intr_mask & (intr_bit)) hw->clr_reg;
|
||||||
FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
|
FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
|
||||||
#undef CLR_INTR
|
#undef CLR_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool spi_ll_get_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline bool spi_ll_get_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define GET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit) && hw->st_reg) return true;
|
#define GET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit) && hw->st_reg) return true;
|
||||||
FOR_EACH_ITEM(GET_INTR, INTR_LIST);
|
FOR_EACH_ITEM(GET_INTR, INTR_LIST);
|
||||||
@@ -1052,7 +1059,7 @@ static inline void spi_ll_enable_int(spi_dev_t *hw)
|
|||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Slave HD
|
* Slave HD
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t* hw, spi_ll_trans_len_cond_t cond_mask)
|
static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t *hw, spi_ll_trans_len_cond_t cond_mask)
|
||||||
{
|
{
|
||||||
hw->slave.rdbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
|
hw->slave.rdbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
|
||||||
hw->slave.wrbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
|
hw->slave.wrbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
|
||||||
@@ -1060,12 +1067,12 @@ static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t* hw, spi_ll_trans_len_
|
|||||||
hw->slave.wrdma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0;
|
hw->slave.wrdma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t* hw)
|
static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t *hw)
|
||||||
{
|
{
|
||||||
return hw->slave1.data_bitlen / 8;
|
return hw->slave1.data_bitlen / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t* hw)
|
static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
|
||||||
{
|
{
|
||||||
return hw->slave1.last_addr;
|
return hw->slave1.last_addr;
|
||||||
}
|
}
|
||||||
|
@@ -344,14 +344,16 @@ static inline void spi_ll_read_buffer(spi_dev_t *hw, uint8_t *buffer_to_rcv, siz
|
|||||||
|
|
||||||
static inline void spi_ll_read_buffer_byte(spi_dev_t *hw, int byte_addr, uint8_t *out_data, int len)
|
static inline void spi_ll_read_buffer_byte(spi_dev_t *hw, int byte_addr, uint8_t *out_data, int len)
|
||||||
{
|
{
|
||||||
while (len>0) {
|
while (len > 0) {
|
||||||
uint32_t word = hw->data_buf[byte_addr/4];
|
uint32_t word = hw->data_buf[byte_addr / 4];
|
||||||
int offset = byte_addr % 4;
|
int offset = byte_addr % 4;
|
||||||
|
|
||||||
int copy_len = 4 - offset;
|
int copy_len = 4 - offset;
|
||||||
if (copy_len > len) copy_len = len;
|
if (copy_len > len) {
|
||||||
|
copy_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(out_data, ((uint8_t*)&word)+offset, copy_len);
|
memcpy(out_data, ((uint8_t *)&word) + offset, copy_len);
|
||||||
byte_addr += copy_len;
|
byte_addr += copy_len;
|
||||||
out_data += copy_len;
|
out_data += copy_len;
|
||||||
len -= copy_len;
|
len -= copy_len;
|
||||||
@@ -369,10 +371,14 @@ static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_addr, uint8_
|
|||||||
int offset = byte_addr % 4;
|
int offset = byte_addr % 4;
|
||||||
|
|
||||||
int copy_len = 4 - offset;
|
int copy_len = 4 - offset;
|
||||||
if (copy_len > len) copy_len = len;
|
if (copy_len > len) {
|
||||||
|
copy_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
//read-modify-write
|
//read-modify-write
|
||||||
if (copy_len != 4) word = hw->data_buf[byte_addr / 4];
|
if (copy_len != 4) {
|
||||||
|
word = hw->data_buf[byte_addr / 4];
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(((uint8_t *)&word) + offset, data, copy_len);
|
memcpy(((uint8_t *)&word) + offset, data, copy_len);
|
||||||
hw->data_buf[byte_addr / 4] = word;
|
hw->data_buf[byte_addr / 4] = word;
|
||||||
@@ -554,7 +560,8 @@ static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id)
|
|||||||
* @param hw Beginning address of the peripheral registers.
|
* @param hw Beginning address of the peripheral registers.
|
||||||
* @param keep_active if 0 don't keep CS activated, else keep CS activated
|
* @param keep_active if 0 don't keep CS activated, else keep CS activated
|
||||||
*/
|
*/
|
||||||
static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active) {
|
static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||||
|
{
|
||||||
hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0;
|
hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,35 +974,35 @@ static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw)
|
|||||||
item(SPI_LL_INTR_CMDA, dma_int_ena.cmda, dma_int_raw.cmda, dma_int_clr.cmda=1)
|
item(SPI_LL_INTR_CMDA, dma_int_ena.cmda, dma_int_raw.cmda, dma_int_clr.cmda=1)
|
||||||
|
|
||||||
|
|
||||||
static inline void spi_ll_enable_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1;
|
#define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1;
|
||||||
FOR_EACH_ITEM(ENA_INTR, INTR_LIST);
|
FOR_EACH_ITEM(ENA_INTR, INTR_LIST);
|
||||||
#undef ENA_INTR
|
#undef ENA_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_disable_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_disable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0;
|
#define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0;
|
||||||
FOR_EACH_ITEM(DIS_INTR, INTR_LIST);
|
FOR_EACH_ITEM(DIS_INTR, INTR_LIST);
|
||||||
#undef DIS_INTR
|
#undef DIS_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_set_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_set_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define SET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit)) hw->st_reg = 1;
|
#define SET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit)) hw->st_reg = 1;
|
||||||
FOR_EACH_ITEM(SET_INTR, INTR_LIST);
|
FOR_EACH_ITEM(SET_INTR, INTR_LIST);
|
||||||
#undef SET_INTR
|
#undef SET_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_clear_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_clear_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define CLR_INTR(intr_bit, _, __, clr_reg) if (intr_mask & (intr_bit)) hw->clr_reg;
|
#define CLR_INTR(intr_bit, _, __, clr_reg) if (intr_mask & (intr_bit)) hw->clr_reg;
|
||||||
FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
|
FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
|
||||||
#undef CLR_INTR
|
#undef CLR_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool spi_ll_get_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline bool spi_ll_get_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define GET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit) && hw->st_reg) return true;
|
#define GET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit) && hw->st_reg) return true;
|
||||||
FOR_EACH_ITEM(GET_INTR, INTR_LIST);
|
FOR_EACH_ITEM(GET_INTR, INTR_LIST);
|
||||||
@@ -1049,7 +1056,7 @@ static inline void spi_ll_enable_int(spi_dev_t *hw)
|
|||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Slave HD
|
* Slave HD
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t* hw, spi_ll_trans_len_cond_t cond_mask)
|
static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t *hw, spi_ll_trans_len_cond_t cond_mask)
|
||||||
{
|
{
|
||||||
hw->slv_rd_byte.rdbuf_bytelen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
|
hw->slv_rd_byte.rdbuf_bytelen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
|
||||||
hw->slv_rd_byte.wrbuf_bytelen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
|
hw->slv_rd_byte.wrbuf_bytelen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
|
||||||
@@ -1057,12 +1064,12 @@ static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t* hw, spi_ll_trans_len_
|
|||||||
hw->slv_rd_byte.wrdma_bytelen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0;
|
hw->slv_rd_byte.wrdma_bytelen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t* hw)
|
static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t *hw)
|
||||||
{
|
{
|
||||||
return hw->slv_rd_byte.data_bytelen;
|
return hw->slv_rd_byte.data_bytelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t* hw)
|
static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
|
||||||
{
|
{
|
||||||
return hw->slave1.last_addr;
|
return hw->slave1.last_addr;
|
||||||
}
|
}
|
||||||
|
@@ -351,7 +351,7 @@ static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_s
|
|||||||
*/
|
*/
|
||||||
static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *data, int len)
|
static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
HAL_ASSERT(byte_id+len <= 64);
|
HAL_ASSERT(byte_id + len <= 64);
|
||||||
HAL_ASSERT(len > 0);
|
HAL_ASSERT(len > 0);
|
||||||
HAL_ASSERT(byte_id >= 0);
|
HAL_ASSERT(byte_id >= 0);
|
||||||
|
|
||||||
@@ -359,10 +359,14 @@ static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t
|
|||||||
uint32_t word;
|
uint32_t word;
|
||||||
int offset = byte_id % 4;
|
int offset = byte_id % 4;
|
||||||
int copy_len = 4 - offset;
|
int copy_len = 4 - offset;
|
||||||
if (copy_len > len) copy_len = len;
|
if (copy_len > len) {
|
||||||
|
copy_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
//read-modify-write
|
//read-modify-write
|
||||||
if (copy_len != 4) word = hw->data_buf[byte_id / 4]; //read
|
if (copy_len != 4) {
|
||||||
|
word = hw->data_buf[byte_id / 4]; //read
|
||||||
|
}
|
||||||
memcpy(((uint8_t *)&word) + offset, data, copy_len); //modify
|
memcpy(((uint8_t *)&word) + offset, data, copy_len); //modify
|
||||||
hw->data_buf[byte_id / 4] = word; //write
|
hw->data_buf[byte_id / 4] = word; //write
|
||||||
|
|
||||||
@@ -406,7 +410,9 @@ static inline void spi_ll_read_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *
|
|||||||
uint32_t word = hw->data_buf[byte_id / 4];
|
uint32_t word = hw->data_buf[byte_id / 4];
|
||||||
int offset = byte_id % 4;
|
int offset = byte_id % 4;
|
||||||
int copy_len = 4 - offset;
|
int copy_len = 4 - offset;
|
||||||
if (copy_len > len) copy_len = len;
|
if (copy_len > len) {
|
||||||
|
copy_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(out_data, ((uint8_t *)&word) + offset, copy_len);
|
memcpy(out_data, ((uint8_t *)&word) + offset, copy_len);
|
||||||
byte_id += copy_len;
|
byte_id += copy_len;
|
||||||
@@ -601,7 +607,8 @@ static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id)
|
|||||||
* @param hw Beginning address of the peripheral registers.
|
* @param hw Beginning address of the peripheral registers.
|
||||||
* @param keep_active if 0 don't keep CS activated, else keep CS activated
|
* @param keep_active if 0 don't keep CS activated, else keep CS activated
|
||||||
*/
|
*/
|
||||||
static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active) {
|
static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||||
|
{
|
||||||
hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0;
|
hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -986,35 +993,35 @@ static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw)
|
|||||||
item(SPI_LL_INTR_CMDA, dma_int_ena.cmda, dma_int_raw.cmda, dma_int_clr.cmda, dma_int_set.cmda_int_set)
|
item(SPI_LL_INTR_CMDA, dma_int_ena.cmda, dma_int_raw.cmda, dma_int_clr.cmda, dma_int_set.cmda_int_set)
|
||||||
|
|
||||||
|
|
||||||
static inline void spi_ll_enable_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1;
|
#define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1;
|
||||||
FOR_EACH_ITEM(ENA_INTR, INTR_LIST);
|
FOR_EACH_ITEM(ENA_INTR, INTR_LIST);
|
||||||
#undef ENA_INTR
|
#undef ENA_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_disable_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_disable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0;
|
#define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0;
|
||||||
FOR_EACH_ITEM(DIS_INTR, INTR_LIST);
|
FOR_EACH_ITEM(DIS_INTR, INTR_LIST);
|
||||||
#undef DIS_INTR
|
#undef DIS_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_set_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_set_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define SET_INTR(intr_bit, _, __, ___, set_reg) if (intr_mask & (intr_bit)) hw->set_reg = 1;
|
#define SET_INTR(intr_bit, _, __, ___, set_reg) if (intr_mask & (intr_bit)) hw->set_reg = 1;
|
||||||
FOR_EACH_ITEM(SET_INTR, INTR_LIST);
|
FOR_EACH_ITEM(SET_INTR, INTR_LIST);
|
||||||
#undef SET_INTR
|
#undef SET_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_ll_clear_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline void spi_ll_clear_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define CLR_INTR(intr_bit, _, __, clr_reg, ...) if (intr_mask & (intr_bit)) hw->clr_reg = 1;
|
#define CLR_INTR(intr_bit, _, __, clr_reg, ...) if (intr_mask & (intr_bit)) hw->clr_reg = 1;
|
||||||
FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
|
FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
|
||||||
#undef CLR_INTR
|
#undef CLR_INTR
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool spi_ll_get_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
|
static inline bool spi_ll_get_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
|
||||||
{
|
{
|
||||||
#define GET_INTR(intr_bit, _, raw_reg, ...) if (intr_mask & (intr_bit) && hw->raw_reg) return true;
|
#define GET_INTR(intr_bit, _, raw_reg, ...) if (intr_mask & (intr_bit) && hw->raw_reg) return true;
|
||||||
FOR_EACH_ITEM(GET_INTR, INTR_LIST);
|
FOR_EACH_ITEM(GET_INTR, INTR_LIST);
|
||||||
@@ -1068,7 +1075,7 @@ static inline void spi_ll_enable_int(spi_dev_t *hw)
|
|||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Slave HD
|
* Slave HD
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t* hw, spi_ll_trans_len_cond_t cond_mask)
|
static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t *hw, spi_ll_trans_len_cond_t cond_mask)
|
||||||
{
|
{
|
||||||
hw->slave.rdbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
|
hw->slave.rdbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
|
||||||
hw->slave.wrbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
|
hw->slave.wrbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
|
||||||
@@ -1076,12 +1083,12 @@ static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t* hw, spi_ll_trans_len_
|
|||||||
hw->slave.wrdma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0;
|
hw->slave.wrdma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t* hw)
|
static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t *hw)
|
||||||
{
|
{
|
||||||
return hw->slave1.data_bitlen / 8;
|
return hw->slave1.data_bitlen / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t* hw)
|
static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
|
||||||
{
|
{
|
||||||
return hw->slave1.last_addr;
|
return hw->slave1.last_addr;
|
||||||
}
|
}
|
||||||
|
@@ -14,8 +14,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include <esp_bit_defs.h>
|
#include "esp_bit_defs.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
@@ -49,9 +50,9 @@ FLAG_ATTR(spi_event_t)
|
|||||||
* @brief Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
|
* @brief Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char cmd_lines; ///< The line width of command phase, e.g. 2-line-cmd-phase.
|
uint8_t cmd_lines; ///< The line width of command phase, e.g. 2-line-cmd-phase.
|
||||||
unsigned char addr_lines; ///< The line width of address phase, e.g. 1-line-addr-phase.
|
uint8_t addr_lines; ///< The line width of address phase, e.g. 1-line-addr-phase.
|
||||||
unsigned char data_lines; ///< The line width of data phase, e.g. 4-line-data-phase.
|
uint8_t data_lines; ///< The line width of data phase, e.g. 4-line-data-phase.
|
||||||
} spi_line_mode_t;
|
} spi_line_mode_t;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -30,8 +30,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S2
|
||||||
@@ -41,8 +40,6 @@ extern "C"
|
|||||||
#define SPI_FWRITE_QIO 0
|
#define SPI_FWRITE_QIO 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Stores a bunch of per-spi-peripheral data.
|
Stores a bunch of per-spi-peripheral data.
|
||||||
*/
|
*/
|
||||||
@@ -53,18 +50,22 @@ typedef struct {
|
|||||||
const uint8_t spiq_out;
|
const uint8_t spiq_out;
|
||||||
const uint8_t spiwp_out;
|
const uint8_t spiwp_out;
|
||||||
const uint8_t spihd_out;
|
const uint8_t spihd_out;
|
||||||
|
#if SOC_SPI_SUPPORT_OCT
|
||||||
const uint8_t spid4_out;
|
const uint8_t spid4_out;
|
||||||
const uint8_t spid5_out;
|
const uint8_t spid5_out;
|
||||||
const uint8_t spid6_out;
|
const uint8_t spid6_out;
|
||||||
const uint8_t spid7_out;
|
const uint8_t spid7_out;
|
||||||
|
#endif // SOC_SPI_SUPPORT_OCT
|
||||||
const uint8_t spid_in; //GPIO mux input signals
|
const uint8_t spid_in; //GPIO mux input signals
|
||||||
const uint8_t spiq_in;
|
const uint8_t spiq_in;
|
||||||
const uint8_t spiwp_in;
|
const uint8_t spiwp_in;
|
||||||
const uint8_t spihd_in;
|
const uint8_t spihd_in;
|
||||||
|
#if SOC_SPI_SUPPORT_OCT
|
||||||
const uint8_t spid4_in;
|
const uint8_t spid4_in;
|
||||||
const uint8_t spid5_in;
|
const uint8_t spid5_in;
|
||||||
const uint8_t spid6_in;
|
const uint8_t spid6_in;
|
||||||
const uint8_t spid7_in;
|
const uint8_t spid7_in;
|
||||||
|
#endif // SOC_SPI_SUPPORT_OCT
|
||||||
const uint8_t spics_out[3]; // /CS GPIO output mux signals
|
const uint8_t spics_out[3]; // /CS GPIO output mux signals
|
||||||
const uint8_t spics_in;
|
const uint8_t spics_in;
|
||||||
const uint8_t spidqs_out;
|
const uint8_t spidqs_out;
|
||||||
|
@@ -47,16 +47,16 @@ Term Definition
|
|||||||
**Host** The SPI controller peripheral inside {IDF_TARGET_NAME} that initiates SPI transmissions over the bus, and acts as an SPI Master.
|
**Host** The SPI controller peripheral inside {IDF_TARGET_NAME} that initiates SPI transmissions over the bus, and acts as an SPI Master.
|
||||||
**Device** SPI slave device. An SPI bus may be connected to one or more Devices. Each Device shares the MOSI, MISO and SCLK signals but is only active on the bus when the Host asserts the Device's individual CS line.
|
**Device** SPI slave device. An SPI bus may be connected to one or more Devices. Each Device shares the MOSI, MISO and SCLK signals but is only active on the bus when the Host asserts the Device's individual CS line.
|
||||||
**Bus** A signal bus, common to all Devices connected to one Host. In general, a bus includes the following lines: MISO, MOSI, SCLK, one or more CS lines, and, optionally, QUADWP and QUADHD. So Devices are connected to the same lines, with the exception that each Device has its own CS line. Several Devices can also share one CS line if connected in the daisy-chain manner.
|
**Bus** A signal bus, common to all Devices connected to one Host. In general, a bus includes the following lines: MISO, MOSI, SCLK, one or more CS lines, and, optionally, QUADWP and QUADHD. So Devices are connected to the same lines, with the exception that each Device has its own CS line. Several Devices can also share one CS line if connected in the daisy-chain manner.
|
||||||
**MISO** Master In, Slave Out, a.k.a. Q. Data transmission from a Device to Host. Also data1 signal in octal mode.
|
**MOSI** Master Out, Slave In, a.k.a. D. Data transmission from a Host to Device. Also data0 signal in Octal/OPI mode.
|
||||||
**MOSI** Master Out, Slave In, a.k.a. D. Data transmission from a Host to Device. Also data0 signal in octal mode.
|
**MISO** Master In, Slave Out, a.k.a. Q. Data transmission from a Device to Host. Also data1 signal in Octal/OPI mode.
|
||||||
**SCLK** Serial Clock. Oscillating signal generated by a Host that keeps the transmission of data bits in sync.
|
**SCLK** Serial Clock. Oscillating signal generated by a Host that keeps the transmission of data bits in sync.
|
||||||
**CS** Chip Select. Allows a Host to select individual Device(s) connected to the bus in order to send or receive data.
|
**CS** Chip Select. Allows a Host to select individual Device(s) connected to the bus in order to send or receive data.
|
||||||
**QUADWP** Write Protect signal. Used for 4-bit (qio/qout) transactions. Also for data2 signal in octal mode.
|
**QUADWP** Write Protect signal. Used for 4-bit (qio/qout) transactions. Also for data2 signal in Octal/OPI mode.
|
||||||
**QUADHD** Hold signal. Used for 4-bit (qio/qout) transactions. Also for data3 signal in octal mode.
|
**QUADHD** Hold signal. Used for 4-bit (qio/qout) transactions. Also for data3 signal in Octal/OPI mode.
|
||||||
**DATA4** Data4 signal in octal mode.
|
**DATA4** Data4 signal in Octal/OPI mode.
|
||||||
**DATA5** Data5 signal in octal mode.
|
**DATA5** Data5 signal in Octal/OPI mode.
|
||||||
**DATA6** Data6 signal in octal mode.
|
**DATA6** Data6 signal in Octal/OPI mode.
|
||||||
**DATA7** Data7 signal in octal mode.
|
**DATA7** Data7 signal in Octal/OPI mode.
|
||||||
**Assertion** The action of activating a line.
|
**Assertion** The action of activating a line.
|
||||||
**De-assertion** The action of returning the line back to inactive (back to idle) status.
|
**De-assertion** The action of returning the line back to inactive (back to idle) status.
|
||||||
**Transaction** One instance of a Host asserting a CS line, transferring data to and from a Device, and de-asserting the CS line. Transactions are atomic, which means they can never be interrupted by another transaction.
|
**Transaction** One instance of a Host asserting a CS line, transferring data to and from a Device, and de-asserting the CS line. Transactions are atomic, which means they can never be interrupted by another transaction.
|
||||||
@@ -148,41 +148,59 @@ All the tasks that use interrupt transactions can be blocked by the queue. At th
|
|||||||
|
|
||||||
The :cpp:func:`spi_device_polling_end` routine needs an overhead of at least 1 us to unblock other tasks when the transaction is finished. It is strongly recommended to wrap a series of polling transactions using the functions :cpp:func:`spi_device_acquire_bus` and :cpp:func:`spi_device_release_bus` to avoid the overhead. For more information, see :ref:`bus_acquiring`.
|
The :cpp:func:`spi_device_polling_end` routine needs an overhead of at least 1 us to unblock other tasks when the transaction is finished. It is strongly recommended to wrap a series of polling transactions using the functions :cpp:func:`spi_device_acquire_bus` and :cpp:func:`spi_device_release_bus` to avoid the overhead. For more information, see :ref:`bus_acquiring`.
|
||||||
|
|
||||||
|
.. _transaction-line-mode:
|
||||||
|
|
||||||
Transaction Line Mode
|
Transaction Line Mode
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Supported line modes are as follows:
|
Supported line modes for {IDF_TARGET_NAME} are listed as follows, to make use of these modes, set the member `flags` in the struct :cpp:type:`spi_transaction_t` as shown in the `Transaction Flag` column. If you want to check if corresponding IO pins are set or not, set the member `flags` in the :cpp:type:`spi_bus_config_t` as shown in the `Bus IO setting Flag` column.
|
||||||
|
|
||||||
====================== ====================== ====================== ==================
|
|
||||||
Mode name Command Line Width Address Line Width Data Line Width
|
|
||||||
====================== ====================== ====================== ==================
|
|
||||||
**Dual Output** 1 1 2
|
|
||||||
**Dual I/O** 1 2 2
|
|
||||||
**Quad Output** 1 1 4
|
|
||||||
**Quad I/O** 1 4 4
|
|
||||||
**Octal Output** 1 1 8
|
|
||||||
**OPI** 8 8 8
|
|
||||||
====================== ====================== ====================== ==================
|
|
||||||
|
|
||||||
|
|
||||||
To make use of these modes, `data0_io_num` to `data7_io_num` I/O pins in the struct :cpp:type:`spi_bus_config_t` and the member `flags` in the struct :cpp:type:`spi_bus_config_t` should be set as shown below:
|
.. only:: not SOC_SPI_SUPPORT_OCT
|
||||||
|
|
||||||
+-------------------+--------------------------+
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
| Mode name | Flags |
|
| Mode name | Command Line Width | Address Line Width | Data Line Width | Transaction Flag | Bus IO setting Flag |
|
||||||
+===================+==========================+
|
+==============+====================+====================+=================+============================+=========================+
|
||||||
| Dual Output | |
|
| Normal SPI | 1 | 1 | 1 | 0 | 0 |
|
||||||
+-------------------+ SPICOMMON_BUSFLAG_DUAL |
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
| Dual I/O | |
|
| Dual Output | 1 | 1 | 2 | SPI_TRANS_MODE_DIO | |
|
||||||
+-------------------+--------------------------+
|
| | | | | | |
|
||||||
| Quad Output | |
|
| | | | | | SPICOMMON_BUSFLAG_DUAL |
|
||||||
+-------------------+ SPICOMMON_BUSFLAG_QUAD |
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
| Quad I/O | |
|
| Dual I/O | 1 | 2 | 2 | SPI_TRANS_MODE_DIO | | |
|
||||||
+-------------------+--------------------------+
|
| | | | | SPI_TRANS_MULTILINE_ADDR | |
|
||||||
| Octal Output | |
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
+-------------------+ SPICOMMON_BUSFLAG_OCTAL |
|
| Quad Output | 1 | 1 | 4 | SPI_TRANS_MODE_QIO | |
|
||||||
| OPI | |
|
+--------------+--------------------+--------------------+-----------------+----------------------------+ |
|
||||||
+-------------------+--------------------------+
|
| Quad I/O | 1 | 4 | 4 | SPI_TRANS_MODE_QIO | | SPICOMMON_BUSFLAG_QUAD |
|
||||||
|
| | | | | SPI_TRANS_MULTILINE_ADDR | |
|
||||||
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
|
|
||||||
|
.. only:: SOC_SPI_SUPPORT_OCT
|
||||||
|
|
||||||
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
|
| Mode name | Command Line Width | Address Line Width | Data Line Width | Transaction Flag | Bus IO setting Flag |
|
||||||
|
+==============+====================+====================+=================+============================+=========================+
|
||||||
|
| Normal SPI | 1 | 1 | 1 | 0 | 0 |
|
||||||
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
|
| Dual Output | 1 | 1 | 2 | SPI_TRANS_MODE_DIO | |
|
||||||
|
| | | | | | |
|
||||||
|
| | | | | | SPICOMMON_BUSFLAG_DUAL |
|
||||||
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
|
| Dual I/O | 1 | 2 | 2 | SPI_TRANS_MODE_DIO | | |
|
||||||
|
| | | | | SPI_TRANS_MULTILINE_ADDR | |
|
||||||
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
|
| Quad Output | 1 | 1 | 4 | SPI_TRANS_MODE_QIO | |
|
||||||
|
+--------------+--------------------+--------------------+-----------------+----------------------------+ |
|
||||||
|
| Quad I/O | 1 | 4 | 4 | SPI_TRANS_MODE_QIO | | SPICOMMON_BUSFLAG_QUAD |
|
||||||
|
| | | | | SPI_TRANS_MULTILINE_ADDR | |
|
||||||
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
|
| Octal Output | 1 | 1 | 8 | SPI_TRANS_MODE_OCT | |
|
||||||
|
+--------------+--------------------+--------------------+-----------------+----------------------------+ |
|
||||||
|
| OPI | 8 | 8 | 8 | SPI_TRANS_MODE_OCT | | SPICOMMON_BUSFLAG_OCTAL |
|
||||||
|
| | | | | SPI_TRANS_MULTILINE_ADDR | | |
|
||||||
|
| | | | | SPI_TRANS_MULTILINE_CMD | |
|
||||||
|
+--------------+--------------------+--------------------+-----------------+----------------------------+-------------------------+
|
||||||
|
|
||||||
Command and Address Phases
|
Command and Address Phases
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@@ -191,7 +209,7 @@ During the command and address phases, the members :cpp:member:`cmd` and :cpp:me
|
|||||||
|
|
||||||
If the lengths of the command and address phases need to be variable, declare the struct :cpp:type:`spi_transaction_ext_t`, set the flags :cpp:type:`SPI_TRANS_VARIABLE_CMD` and/or :cpp:type:`SPI_TRANS_VARIABLE_ADDR` in the member :cpp:member:`spi_transaction_ext_t::base` and configure the rest of base as usual. Then the length of each phase will be equal to :cpp:member:`command_bits` and :cpp:member:`address_bits` set in the struct :cpp:type:`spi_transaction_ext_t`.
|
If the lengths of the command and address phases need to be variable, declare the struct :cpp:type:`spi_transaction_ext_t`, set the flags :cpp:type:`SPI_TRANS_VARIABLE_CMD` and/or :cpp:type:`SPI_TRANS_VARIABLE_ADDR` in the member :cpp:member:`spi_transaction_ext_t::base` and configure the rest of base as usual. Then the length of each phase will be equal to :cpp:member:`command_bits` and :cpp:member:`address_bits` set in the struct :cpp:type:`spi_transaction_ext_t`.
|
||||||
|
|
||||||
If using more than one data lines to transmit, please set flags at the member `flags` in the struct :cpp:type:`spi_transaction_t`. If the number of lines transmitting command is the same as that transmitting data, please set `MULTILINE_CMD`. If the number of lines transmitting address is the same as that transmitting data, please set `MULTILINE_ADDR`.
|
If the command and address phase need to be as the same number of lines as data phase, you need to set `SPI_TRANS_MULTILINE_CMD` and/or `SPI_TRANS_MULTILINE_ADDR` to the `flags` member in the struct :cpp:type:`spi_transaction_t`. Also see :ref:`transaction-line-mode`.
|
||||||
|
|
||||||
|
|
||||||
Write and Read Phases
|
Write and Read Phases
|
||||||
@@ -204,23 +222,7 @@ Normally, the data that needs to be transferred to or from a Device will be read
|
|||||||
|
|
||||||
If these requirements are not satisfied, the transaction efficiency will be affected due to the allocation and copying of temporary buffers.
|
If these requirements are not satisfied, the transaction efficiency will be affected due to the allocation and copying of temporary buffers.
|
||||||
|
|
||||||
If using more than one data lines to transmit, please set `SPI_DEVICE_HALFDUPLEX` flag at the member `flags` in the struct :cpp:type:`spi_device_interface_config_t`. And the member `flags` in the struct :cpp:type:`spi_transaction_t` should be set as below:
|
If using more than one data lines to transmit, please set `SPI_DEVICE_HALFDUPLEX` flag for the member `flags` in the struct :cpp:type:`spi_device_interface_config_t`. And the member `flags` in the struct :cpp:type:`spi_transaction_t` should be set as described in :ref:`transaction-line-mode`.
|
||||||
|
|
||||||
+-------------------+--------------------+
|
|
||||||
| Mode name | Flags |
|
|
||||||
+===================+====================+
|
|
||||||
| Dual Output | |
|
|
||||||
+-------------------+ SPI_TRANS_MODE_DIO |
|
|
||||||
| Dual I/O | |
|
|
||||||
+-------------------+--------------------+
|
|
||||||
| Quad Output | |
|
|
||||||
+-------------------+ SPI_TRANS_MODE_QIO |
|
|
||||||
| Quad I/O | |
|
|
||||||
+-------------------+--------------------+
|
|
||||||
| Octal Output | |
|
|
||||||
+-------------------+ SPI_TRANS_MODE_OCT |
|
|
||||||
| OPI | |
|
|
||||||
+-------------------+--------------------+
|
|
||||||
|
|
||||||
.. only:: esp32
|
.. only:: esp32
|
||||||
|
|
||||||
|
@@ -20,65 +20,60 @@ If you want to adapt this example to another type of display or pinout, check [l
|
|||||||
|
|
||||||
### Hardware Connection
|
### Hardware Connection
|
||||||
|
|
||||||
If using default settings, the hardware connection can be as below:
|
The connection between ESP Board and the LCD is as follows:
|
||||||
|
|
||||||
```
|
```
|
||||||
Board LCD Screen
|
ESP Board LCD Screen
|
||||||
+--------+ +---------------------------------+
|
+---------+ +---------------------------------+
|
||||||
| | | |
|
| | | |
|
||||||
| 3V3 +--------------+ VCC +----------------------+ |
|
| 3V3 +--------------+ VCC +----------------------+ |
|
||||||
| | | | | |
|
| | | | | |
|
||||||
| GND +--------------+ GND | | |
|
| GND +--------------+ GND | | |
|
||||||
| | | | | |
|
| | | | | |
|
||||||
| 23 +--------------+ MOSI | | |
|
| DATA0 +--------------+ MOSI | | |
|
||||||
| | | | | |
|
| | | | | |
|
||||||
| 19 +--------------+ SCK | | |
|
| PCLK +--------------+ SCK | | |
|
||||||
| | | | | |
|
| | | | | |
|
||||||
| 22 +--------------+ CS | | |
|
| CS +--------------+ CS | | |
|
||||||
| | | | | |
|
| | | | | |
|
||||||
| 21 +--------------+ DC | | |
|
| D/C +--------------+ D/C | | |
|
||||||
| | | | | |
|
| | | | | |
|
||||||
| 18 +--------------+ RST | | |
|
| RST +--------------+ RST | | |
|
||||||
| | | | | |
|
| | | | | |
|
||||||
| 5 +--------------+ BCKL +----------------------+ |
|
|BK_LIGHT +--------------+ BCKL +----------------------+ |
|
||||||
| | | |
|
| | | |
|
||||||
+--------+ +---------------------------------+
|
+---------+ +---------------------------------+
|
||||||
```
|
```
|
||||||
|
|
||||||
If not using default settings, the interface GPIOs should be set by macros in [lcd_tjpgd_example_main.c](main/lcd_tjpgd_example_main.c), where:
|
The GPIO number used by this example can be changed in [lcd_tjpgd_example_main.c](main/lcd_tjpgd_example_main.c), where:
|
||||||
|
|
||||||
| GPIO number | LCD pin |
|
| GPIO number | LCD pin |
|
||||||
| :-----------: | :--: |
|
| ------------------------ | ------- |
|
||||||
| PIN_NUM_CLK | SCK |
|
| EXAMPLE_PIN_NUM_PCLK | SCK |
|
||||||
| PIN_NUM_CS | CS |
|
| EXAMPLE_PIN_NUM_CS | CS |
|
||||||
| PIN_NUM_DC | DC |
|
| EXAMPLE_PIN_NUM_DC | DC |
|
||||||
| PIN_NUM_RST | RST |
|
| EXAMPLE_PIN_NUM_RST | RST |
|
||||||
| PIN_NUM_BCKL | LED |
|
| EXAMPLE_PIN_NUM_DATA0 | MOSI |
|
||||||
| PIN_NUM_MOSI | MOSI |
|
| EXAMPLE_PIN_NUM_BK_LIGHT | BCKL |
|
||||||
|
|
||||||
|
Especially, please pay attention to the level used to turn on the LCD backlight, some LCD module needs a low level to turn it on, while others take a high level. You can change the backlight level macro `EXAMPLE_LCD_BK_LIGHT_ON_LEVEL` in [lcd_tjpgd_example_main.c](main/lcd_tjpgd_example_main.c).
|
||||||
|
|
||||||
|
|
||||||
### 8-line LCD Usage
|
#### Extra connections for 8-line LCD (Octal SPI)
|
||||||
|
|
||||||
Firstly, please run `idf.py menuconfig` and set the `Drive a LCD with 8 data lines` option at `Example Configuration`.
|
Firstly, please run `idf.py menuconfig` and set the `Drive a LCD with 8 data lines` option at `Example Configuration`.
|
||||||
|
|
||||||
Check if the pins below are correctly connected as the settings by macros in [lcd_tjpgd_example_main.c](main/lcd_tjpgd_example_main.c), where:
|
Change the extra GPOIs used by octal SPI in [lcd_tjpgd_example_main.c](main/lcd_tjpgd_example_main.c), where:
|
||||||
|
|
||||||
| GPIO number | LCD pin |
|
| GPIO number | LCD pin |
|
||||||
| :-----------: | :--: |
|
| ------------- | ------- |
|
||||||
| PIN_NUM_CLK | SCK |
|
| PIN_NUM_DATA1 | D1 |
|
||||||
| PIN_NUM_CS | CS |
|
| PIN_NUM_DATA2 | D2 |
|
||||||
| PIN_NUM_DC | DC |
|
| PIN_NUM_DATA3 | D3 |
|
||||||
| PIN_NUM_RST | RST |
|
| PIN_NUM_DATA4 | D4 |
|
||||||
| PIN_NUM_BCKL | LED |
|
| PIN_NUM_DATA5 | D5 |
|
||||||
| PIN_NUM_MOSI | D0 |
|
| PIN_NUM_DATA6 | D6 |
|
||||||
| PIN_NUM_DATA1 | D1 |
|
| PIN_NUM_DATA7 | D7 |
|
||||||
| PIN_NUM_DATA2 | D2 |
|
|
||||||
| PIN_NUM_DATA3 | D3 |
|
|
||||||
| PIN_NUM_DATA4 | D4 |
|
|
||||||
| PIN_NUM_DATA5 | D5 |
|
|
||||||
| PIN_NUM_DATA6 | D6 |
|
|
||||||
| PIN_NUM_DATA7 | D7 |
|
|
||||||
|
|
||||||
|
|
||||||
### Build and Flash
|
### Build and Flash
|
||||||
|
|
||||||
|
@@ -1,15 +1,5 @@
|
|||||||
menu "Example Configuration"
|
menu "Example Configuration"
|
||||||
|
config EXAMPLE_LCD_SPI_8_LINE_MODE
|
||||||
config LCD_OVERCLOCK
|
|
||||||
bool
|
|
||||||
prompt "Run LCD at higher clock speed than allowed"
|
|
||||||
default "n"
|
|
||||||
help
|
|
||||||
The ILI9341 and ST7789 specify that the maximum clock speed for the SPI interface is 10MHz. However,
|
|
||||||
in practice the driver chips work fine with a higher clock rate, and using that gives a better framerate.
|
|
||||||
Select this to try using the out-of-spec clock rate.
|
|
||||||
|
|
||||||
config LCD_SPI_8_LINE_MODE
|
|
||||||
bool
|
bool
|
||||||
prompt "Drive a LCD with 8 data lines"
|
prompt "Drive a LCD with 8 data lines"
|
||||||
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||||
|
@@ -12,47 +12,49 @@
|
|||||||
#include "esp_lcd_panel_io.h"
|
#include "esp_lcd_panel_io.h"
|
||||||
#include "esp_lcd_panel_vendor.h"
|
#include "esp_lcd_panel_vendor.h"
|
||||||
#include "esp_lcd_panel_ops.h"
|
#include "esp_lcd_panel_ops.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
#include "driver/spi_master.h"
|
#include "driver/spi_master.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "pretty_effect.h"
|
#include "pretty_effect.h"
|
||||||
|
|
||||||
#define LCD_HOST SPI2_HOST /*!< spi peripheral for LCD */
|
// Using SPI2 in the example, as it aslo supports octal modes on some targets
|
||||||
|
#define LCD_HOST SPI2_HOST
|
||||||
/**
|
|
||||||
* If not using the default settings, the SPI peripheral on LCD and the GPIO numbers can be
|
|
||||||
* changed below.
|
|
||||||
*/
|
|
||||||
#define PIN_NUM_MOSI 23 /*!< gpio number for LCD MOSI, also the gpio number for LCD DATA0 at 8-line mode */
|
|
||||||
#define PIN_NUM_CLK 19 /*!< gpio number for LCD clock */
|
|
||||||
#define PIN_NUM_CS 22 /*!< gpio number for LCD CS */
|
|
||||||
#define PIN_NUM_DC 21 /*!< gpio number for LCD DC */
|
|
||||||
#define PIN_NUM_RST 18 /*!< gpio number for LCD RST */
|
|
||||||
#define PIN_NUM_BCKL 5 /*!< gpio number for LCD Back Light */
|
|
||||||
#ifdef CONFIG_LCD_SPI_8_LINE_MODE // If using 8-line LCD
|
|
||||||
#define PIN_NUM_DATA1 6 /*!< gpio number for LCD DATA1 */
|
|
||||||
#define PIN_NUM_DATA2 7 /*!< gpio number for LCD DATA2 */
|
|
||||||
#define PIN_NUM_DATA3 8 /*!< gpio number for LCD DATA3 */
|
|
||||||
#define PIN_NUM_DATA4 9 /*!< gpio number for LCD DATA4 */
|
|
||||||
#define PIN_NUM_DATA5 10 /*!< gpio number for LCD DATA5 */
|
|
||||||
#define PIN_NUM_DATA6 11 /*!< gpio number for LCD DATA6 */
|
|
||||||
#define PIN_NUM_DATA7 12 /*!< gpio number for LCD DATA7 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The pixel number in horizontal and vertical
|
|
||||||
#define EXAMPLE_LCD_H_RES (320)
|
|
||||||
#define EXAMPLE_LCD_V_RES (240)
|
|
||||||
|
|
||||||
// The SPI mode supported by the LCD
|
|
||||||
#define LCD_SPI_MODE 0
|
|
||||||
|
|
||||||
// To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many.
|
// To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many.
|
||||||
// More means more memory use, but less overhead for setting up / finishing transfers. Make sure 240
|
// More means more memory use, but less overhead for setting up / finishing transfers. Make sure 240
|
||||||
// is dividable by this.
|
// is dividable by this.
|
||||||
#define PARALLEL_LINES 16
|
#define PARALLEL_LINES 16
|
||||||
|
|
||||||
// The number of frames to show before rotate the graph
|
// The number of frames to show before rotate the graph
|
||||||
#define ROTATE_FRAME 30
|
#define ROTATE_FRAME 30
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////// Please update the following configuration according to your LCD spec //////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (10 * 1000 * 1000)
|
||||||
|
#define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL 0
|
||||||
|
#define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL
|
||||||
|
#define EXAMPLE_PIN_NUM_DATA0 23 /*!< for 1-line SPI, this also refered as MOSI */
|
||||||
|
#define EXAMPLE_PIN_NUM_PCLK 19
|
||||||
|
#define EXAMPLE_PIN_NUM_CS 22
|
||||||
|
#define EXAMPLE_PIN_NUM_DC 21
|
||||||
|
#define EXAMPLE_PIN_NUM_RST 18
|
||||||
|
#define EXAMPLE_PIN_NUM_BK_LIGHT 5
|
||||||
|
|
||||||
|
// The pixel number in horizontal and vertical
|
||||||
|
#define EXAMPLE_LCD_H_RES 320
|
||||||
|
#define EXAMPLE_LCD_V_RES 240
|
||||||
|
// Bit number used to represent command and parameter
|
||||||
|
#define EXAMPLE_LCD_CMD_BITS 8
|
||||||
|
#define EXAMPLE_LCD_PARAM_BITS 8
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_LCD_SPI_8_LINE_MODE
|
||||||
|
#define EXAMPLE_PIN_NUM_DATA1 7
|
||||||
|
#define EXAMPLE_PIN_NUM_DATA2 8
|
||||||
|
#define EXAMPLE_PIN_NUM_DATA3 9
|
||||||
|
#define EXAMPLE_PIN_NUM_DATA4 10
|
||||||
|
#define EXAMPLE_PIN_NUM_DATA5 11
|
||||||
|
#define EXAMPLE_PIN_NUM_DATA6 12
|
||||||
|
#define EXAMPLE_PIN_NUM_DATA7 13
|
||||||
|
#endif // CONFIG_EXAMPLE_LCD_SPI_8_LINE_MODE
|
||||||
|
|
||||||
// Simple routine to generate some patterns and send them to the LCD. Because the
|
// Simple routine to generate some patterns and send them to the LCD. Because the
|
||||||
// SPI driver handles transactions in the background, we can calculate the next line
|
// SPI driver handles transactions in the background, we can calculate the next line
|
||||||
@@ -83,54 +85,52 @@ void app_main(void)
|
|||||||
{
|
{
|
||||||
gpio_config_t bk_gpio_config = {
|
gpio_config_t bk_gpio_config = {
|
||||||
.mode = GPIO_MODE_OUTPUT,
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
.pin_bit_mask = 1ULL << PIN_NUM_BCKL
|
.pin_bit_mask = 1ULL << EXAMPLE_PIN_NUM_BK_LIGHT
|
||||||
};
|
};
|
||||||
// Initialize the GPIO of backlight
|
// Initialize the GPIO of backlight
|
||||||
ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
|
ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
|
||||||
|
|
||||||
spi_bus_config_t buscfg = {
|
spi_bus_config_t buscfg = {
|
||||||
.mosi_io_num = PIN_NUM_MOSI,
|
.sclk_io_num = EXAMPLE_PIN_NUM_PCLK,
|
||||||
.sclk_io_num = PIN_NUM_CLK,
|
.mosi_io_num = EXAMPLE_PIN_NUM_DATA0,
|
||||||
#ifdef CONFIG_LCD_SPI_8_LINE_MODE
|
|
||||||
.data1_io_num = PIN_NUM_DATA1,
|
|
||||||
.data2_io_num = PIN_NUM_DATA2,
|
|
||||||
.data3_io_num = PIN_NUM_DATA3,
|
|
||||||
.data4_io_num = PIN_NUM_DATA4,
|
|
||||||
.data5_io_num = PIN_NUM_DATA5,
|
|
||||||
.data6_io_num = PIN_NUM_DATA6,
|
|
||||||
.data7_io_num = PIN_NUM_DATA7,
|
|
||||||
.flags = SPICOMMON_BUSFLAG_OCTAL,
|
|
||||||
#else
|
|
||||||
.miso_io_num = -1,
|
.miso_io_num = -1,
|
||||||
.quadwp_io_num = -1,
|
.quadwp_io_num = -1,
|
||||||
.quadhd_io_num = -1,
|
.quadhd_io_num = -1,
|
||||||
#endif
|
|
||||||
.max_transfer_sz = PARALLEL_LINES * EXAMPLE_LCD_H_RES * 2 + 8
|
.max_transfer_sz = PARALLEL_LINES * EXAMPLE_LCD_H_RES * 2 + 8
|
||||||
};
|
};
|
||||||
esp_lcd_panel_io_handle_t io_handle = NULL;
|
#if CONFIG_EXAMPLE_LCD_SPI_8_LINE_MODE
|
||||||
esp_lcd_panel_io_spi_config_t io_config = {
|
buscfg.data1_io_num = EXAMPLE_PIN_NUM_DATA1;
|
||||||
.dc_gpio_num = PIN_NUM_DC,
|
buscfg.data2_io_num = EXAMPLE_PIN_NUM_DATA2;
|
||||||
.cs_gpio_num = PIN_NUM_CS,
|
buscfg.data3_io_num = EXAMPLE_PIN_NUM_DATA3;
|
||||||
#ifdef CONFIG_LCD_OVERCLOCK
|
buscfg.data4_io_num = EXAMPLE_PIN_NUM_DATA4;
|
||||||
.pclk_hz = 26 * 1000 * 1000, // Clock out at 26 MHz
|
buscfg.data5_io_num = EXAMPLE_PIN_NUM_DATA5;
|
||||||
#else
|
buscfg.data6_io_num = EXAMPLE_PIN_NUM_DATA6;
|
||||||
.pclk_hz = 10 * 1000 * 1000, // Clock out at 10 MHz
|
buscfg.data7_io_num = EXAMPLE_PIN_NUM_DATA7;
|
||||||
|
buscfg.flags = SPICOMMON_BUSFLAG_OCTAL;
|
||||||
#endif
|
#endif
|
||||||
.spi_mode = LCD_SPI_MODE,
|
|
||||||
.trans_queue_depth = 7,
|
|
||||||
#ifdef CONFIG_LCD_SPI_8_LINE_MODE
|
|
||||||
.flags.octal_mode = 1,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
// Initialize the SPI bus
|
// Initialize the SPI bus
|
||||||
ESP_ERROR_CHECK(spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO));
|
ESP_ERROR_CHECK(spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO));
|
||||||
|
|
||||||
|
esp_lcd_panel_io_handle_t io_handle = NULL;
|
||||||
|
esp_lcd_panel_io_spi_config_t io_config = {
|
||||||
|
.dc_gpio_num = EXAMPLE_PIN_NUM_DC,
|
||||||
|
.cs_gpio_num = EXAMPLE_PIN_NUM_CS,
|
||||||
|
.pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
|
||||||
|
.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
|
||||||
|
.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,
|
||||||
|
.spi_mode = 0,
|
||||||
|
.trans_queue_depth = 10,
|
||||||
|
};
|
||||||
|
#if CONFIG_EXAMPLE_LCD_SPI_8_LINE_MODE
|
||||||
|
io_config.spi_mode = 3; // using mode 3 to simulate Intel 8080 timing
|
||||||
|
io_config.flags.octal_mode = 1;
|
||||||
|
#endif
|
||||||
// Attach the LCD to the SPI bus
|
// Attach the LCD to the SPI bus
|
||||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &io_config, &io_handle));
|
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &io_config, &io_handle));
|
||||||
|
|
||||||
|
|
||||||
esp_lcd_panel_handle_t panel_handle = NULL;
|
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||||
esp_lcd_panel_dev_config_t panel_config = {
|
esp_lcd_panel_dev_config_t panel_config = {
|
||||||
.reset_gpio_num = PIN_NUM_RST,
|
.reset_gpio_num = EXAMPLE_PIN_NUM_RST,
|
||||||
.color_space = ESP_LCD_COLOR_SPACE_BGR,
|
.color_space = ESP_LCD_COLOR_SPACE_BGR,
|
||||||
.bits_per_pixel = 16,
|
.bits_per_pixel = 16,
|
||||||
};
|
};
|
||||||
@@ -139,7 +139,7 @@ void app_main(void)
|
|||||||
|
|
||||||
// Turn off backlight to avoid unpredictable display on the LCD screen while initializing
|
// Turn off backlight to avoid unpredictable display on the LCD screen while initializing
|
||||||
// the LCD panel driver. (Different LCD screens may need different levels)
|
// the LCD panel driver. (Different LCD screens may need different levels)
|
||||||
ESP_ERROR_CHECK(gpio_set_level(PIN_NUM_BCKL, 1));
|
ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL));
|
||||||
|
|
||||||
// Reset the display
|
// Reset the display
|
||||||
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
|
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
|
||||||
@@ -151,7 +151,7 @@ void app_main(void)
|
|||||||
ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, true));
|
ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, true));
|
||||||
|
|
||||||
// Turn on backlight (Different LCD screens may need different levels)
|
// Turn on backlight (Different LCD screens may need different levels)
|
||||||
ESP_ERROR_CHECK(gpio_set_level(PIN_NUM_BCKL, 0));
|
ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_ON_LEVEL));
|
||||||
|
|
||||||
// Initialize the effect displayed
|
// Initialize the effect displayed
|
||||||
ESP_ERROR_CHECK(pretty_effect_init());
|
ESP_ERROR_CHECK(pretty_effect_init());
|
||||||
@@ -173,5 +173,4 @@ void app_main(void)
|
|||||||
display_pretty_colors(panel_handle);
|
display_pretty_colors(panel_handle);
|
||||||
is_rotated = !is_rotated;
|
is_rotated = !is_rotated;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user