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
/* 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");
}