You can chat about native SDK questions and issues here.

User avatar
By JaaberMatt
#89977 Hi there,

I'm writing a little program to drive an 1.54" Epaper display from WaveShare using a 4 wire SPI interface. After following the datasheet, I tryied to make my ESP12-F communicate properly with the display. However the screen does not react at all....
I think my wiring is right, but it must be a stupid mistake in my code.
Any help would be really appreciated !

The board i'm using : Here

The display : Here

Code: Select all/* spi_epaper example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include <stdio.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

#include "esp8266/gpio_struct.h"
#include "esp8266/spi_struct.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_libc.h"

#include "driver/gpio.h"
#include "driver/spi.h"

#define EPD_WIDTH       200
#define EPD_HEIGHT      200

static const char *TAG = "spi_epaper";

#define EPAPER_DC_GPIO     12
#define EPAPER_RST_GPIO    15
#define EPAPER_CS_GPIO      4
#define EPAPER_BSY_GPIO     2
#define EPAPER_PIN_OUTPUT_SEL  (1ULL<<EPAPER_DC_GPIO) | (1ULL<<EPAPER_RST_GPIO) | (1ULL<<EPAPER_CS_GPIO)
#define EPAPER_PIN_INPUT_SEL (1ULL<<EPAPER_BSY_GPIO)

static esp_err_t delay_ms(uint32_t time)
{
    vTaskDelay(time / portTICK_RATE_MS);
    return ESP_OK;
}

static esp_err_t waitUntilIdle(){

    while(gpio_get_level(EPAPER_BSY_GPIO) == 1) {     
      delay_ms(100);
   }

    delay_ms(100);

    return ESP_OK;
}


static esp_err_t epaper_set_dc(uint32_t level){
    gpio_set_level(EPAPER_DC_GPIO,level);
    return ESP_OK;
}

static esp_err_t begin_spi_transaction(){
   
    //Begin transaction
    gpio_set_level(EPAPER_CS_GPIO,0);

    return ESP_OK;
}


static esp_err_t end_spi_transaction(){
   
    //End transaction
    gpio_set_level(EPAPER_CS_GPIO,1);

    return ESP_OK;
}

// Write an 8-bit cmd
static esp_err_t epaper_write_cmd(uint8_t cmd){

    //Prepare data structure
    uint32_t buf = ((uint32_t) cmd) << 24; // In order to improve the transmission efficiency, it is recommended that the external incoming data is (uint32_t *) type data, do not use other type data.
    spi_trans_t trans = {0};
    trans.mosi = &buf;
    trans.bits.mosi = 8;
    epaper_set_dc(0);
   
    //Begin transaction
    begin_spi_transaction();
   
    //Set 8 bits of commands
    spi_trans(HSPI_HOST, &trans);

    //End transaction
    end_spi_transaction();

    return ESP_OK;
}

static esp_err_t epaper_write_data(uint8_t data){

    //Prepare data structure
    uint32_t buf = ((uint32_t)data) << 24; // In order to improve the transmission efficiency, it is recommended that the external incoming data is (uint32_t *) type data, do not use other type data.
    spi_trans_t trans = {0};
    trans.mosi = &buf;
    trans.bits.mosi = 8;
    epaper_set_dc(1);

    //Begin transaction
    begin_spi_transaction();

    //Set 8 bits of commands
    spi_trans(HSPI_HOST, &trans);

    //End transaction
    end_spi_transaction();

    return ESP_OK;
}


static esp_err_t epaper_rst()
{
    gpio_set_level(EPAPER_RST_GPIO, 1);
    delay_ms(200);
    gpio_set_level(EPAPER_RST_GPIO, 0);
    delay_ms(10);
    gpio_set_level(EPAPER_RST_GPIO, 1);
    delay_ms(200);
    return ESP_OK;
}


static esp_err_t epaper_init()
{
    epaper_rst(); // Reset EPAPER

    waitUntilIdle();
   
    epaper_write_cmd(0x12);

    waitUntilIdle();

    epaper_write_cmd(0x01);
    epaper_write_data(0xC7);
    epaper_write_data(0x00);
    epaper_write_data(0x00);


    epaper_write_cmd(0x11);
    epaper_write_data(0x03);


    epaper_write_cmd(0x44);
    epaper_write_data((0 >> 3) & 0xFF);
    epaper_write_data((200 >> 3) & 0xFF);

    epaper_write_cmd(0x45);
    epaper_write_data(0 & 0xFF);
    epaper_write_data((0 >> 8) & 0xFF);
    epaper_write_data(200 & 0xFF);
    epaper_write_data((200 >> 8) & 0xFF);

    epaper_write_cmd(0x3C);
    epaper_write_data(0x01);

    epaper_write_cmd(0x18);
    epaper_write_data(0x80);

    epaper_write_cmd(0x22);
    epaper_write_data(0xB1);
 
    epaper_write_cmd(0x20);

    waitUntilIdle();

    epaper_write_cmd(0x4E);
    epaper_write_data(0x00);

    epaper_write_cmd(0x4F);
    epaper_write_data(0xC7);
    epaper_write_data(0x00);

    waitUntilIdle();

   int w, h;
   w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
   h = EPD_HEIGHT;
 
   epaper_write_cmd(0x24);
   for (int j = 0; j < h; j++) {
      for (int i = 0; i < w; i++) {
         epaper_write_data(0xFF);
      }
   }

    epaper_write_cmd(0x22);
    epaper_write_data(0xF7);
    epaper_write_data(0x20);

    waitUntilIdle();

   // epaper_write_cmd(0x10);
   // epaper_write_data(0x01); 

    return ESP_OK;
}


static void IRAM_ATTR spi_event_callback(int event, void *arg)
{
    switch (event) {
        case SPI_INIT_EVENT: {
           
        }
        break;

        case SPI_TRANS_START_EVENT: {
           // gpio_set_level(EPAPER_DC_GPIO, epaper_dc_level);
        }
        break;

        case SPI_TRANS_DONE_EVENT: {

        }
        break;

        case SPI_DEINIT_EVENT: {
        }
        break;
    }
}

void app_main(void)
{
    uint8_t x = 0;

    //Init output GPIO
    ESP_LOGI(TAG, "init output gpio");
    gpio_config_t io_conf = {0};
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_OUTPUT;
    io_conf.pin_bit_mask = EPAPER_PIN_OUTPUT_SEL;
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 1;
    gpio_config(&io_conf);

    //Init input GPIO
    ESP_LOGI(TAG, "init input gpio");
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pin_bit_mask = EPAPER_PIN_INPUT_SEL;
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 0;
    gpio_config(&io_conf);

    //Init the SPI interface
    ESP_LOGI(TAG, "init hspi");
    spi_config_t spi_config = {0};
    // Load default interface parameters
    // CS_EN:1, MISO_EN:1, MOSI_EN:1, BYTE_TX_ORDER:1, BYTE_TX_ORDER:1, BIT_RX_ORDER:0, BIT_TX_ORDER:0, CPHA:0, CPOL:0
    spi_config.interface.val = SPI_DEFAULT_INTERFACE;
    // Load default interrupt enable
    // TRANS_DONE: true, WRITE_STATUS: false, READ_STATUS: false, WRITE_BUFFER: false, READ_BUFFER: false
    spi_config.intr_enable.val = SPI_MASTER_DEFAULT_INTR_ENABLE;
    // Cancel hardware cs
    spi_config.interface.cs_en = 0;
    // MISO pin is used for DC
    spi_config.interface.miso_en = 0;
    // CPOL: 0, CPHA: 0
    spi_config.interface.cpol = 1;
    spi_config.interface.cpha = 1;
    // Set SPI to master mode
    // 8266 Only support half-duplex
    spi_config.mode = SPI_MASTER_MODE;
    // Set the SPI clock frequency division factor
    spi_config.clk_div = SPI_2MHz_DIV;
    // Register SPI event callback function
    //spi_config.event_cb = spi_event_callback;

    spi_config.interface.byte_tx_order = SPI_BYTE_ORDER_MSB_FIRST;
    spi_config.interface.bit_tx_order = SPI_BIT_ORDER_LSB_FIRST;
    spi_init(HSPI_HOST, &spi_config);

    ESP_LOGI(TAG, "init epaper");
    epaper_init();

    ESP_LOGI(TAG, "Init sequence done");
}
You do not have the required permissions to view the files attached to this post.