Initial commit

This commit is contained in:
Shuanglei Tao
2024-11-11 15:24:18 +08:00
commit f353d23368
1503 changed files with 324924 additions and 0 deletions

91
EPD/DEV_Config.c Normal file
View File

@@ -0,0 +1,91 @@
/*****************************************************************************
* | File : DEV_Config.cpp
* | Author : Waveshare team
* | Function :
* | Info :
* Image scanning
* Please use progressive scanning to generate images or fonts
*----------------
* | This version: V1.0
* | Date : 2018-01-11
* | Info : Basic version
*
******************************************************************************/
#include "nrf_drv_spi.h"
#include "DEV_Config.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
uint32_t EPD_MOSI_PIN = 5;
uint32_t EPD_SCLK_PIN = 8;
uint32_t EPD_CS_PIN = 9;
uint32_t EPD_DC_PIN = 10;
uint32_t EPD_RST_PIN = 11;
uint32_t EPD_BUSY_PIN = 12;
uint32_t EPD_BS_PIN = 13;
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(0);
/******************************************************************************
function: Initialize Arduino, Initialize Pins, and SPI
parameter:
Info:
******************************************************************************/
UBYTE DEV_Module_Init(void)
{
nrf_gpio_cfg_output(EPD_CS_PIN);
nrf_gpio_cfg_output(EPD_DC_PIN);
nrf_gpio_cfg_output(EPD_RST_PIN);
nrf_gpio_cfg_input(EPD_BUSY_PIN, NRF_GPIO_PIN_NOPULL);
nrf_gpio_cfg_output(EPD_BS_PIN);
DEV_Digital_Write(EPD_BS_PIN, 0);
nrf_drv_spi_config_t spi_config =
{
.sck_pin = EPD_SCLK_PIN,
.mosi_pin = EPD_MOSI_PIN,
.miso_pin = NRF_DRV_SPI_PIN_NOT_USED,
.ss_pin = NRF_DRV_SPI_PIN_NOT_USED,
.frequency = NRF_DRV_SPI_FREQ_4M,
.mode = NRF_DRV_SPI_MODE_0,
};
nrf_drv_spi_init(&spi, &spi_config, NULL);
DEV_Digital_Write(EPD_DC_PIN, 0);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_Digital_Write(EPD_RST_PIN, 1);
return 0;
}
/*********************************************
function: Hardware interface
note:
SPI4W_Write_Byte(value) :
Register hardware SPI
*********************************************/
void DEV_SPI_WriteByte(UBYTE value)
{
nrf_drv_spi_transfer(&spi, &value, 1, NULL, 0);
}
UBYTE DEV_SPI_ReadByte(void)
{
UBYTE value;
nrf_drv_spi_transfer(&spi, NULL, 0, &value, 1);
return value;
}
void DEV_Module_Exit(void)
{
DEV_Digital_Write(EPD_DC_PIN, 0);
DEV_Digital_Write(EPD_CS_PIN, 0);
//close 5V
DEV_Digital_Write(EPD_RST_PIN, 0);
nrf_drv_spi_uninit(&spi);
}

56
EPD/DEV_Config.h Normal file
View File

@@ -0,0 +1,56 @@
/*****************************************************************************
* | File : DEV_Config.h
* | Author : Waveshare team
* | Function : debug with prntf
* | Info :
* Image scanning
* Please use progressive scanning to generate images or fonts
*----------------
* | This version: V1.0
* | Date : 2018-01-11
* | Info : Basic version
*
******************************************************************************/
#ifndef _DEV_CONFIG_H_
#define _DEV_CONFIG_H_
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include <stdint.h>
#include <stdlib.h>
/**
* data
**/
#define UBYTE uint8_t
#define UWORD uint16_t
#define UDOUBLE uint32_t
extern uint32_t EPD_MOSI_PIN;
extern uint32_t EPD_SCLK_PIN;
extern uint32_t EPD_CS_PIN;
extern uint32_t EPD_DC_PIN;
extern uint32_t EPD_RST_PIN;
extern uint32_t EPD_BUSY_PIN;
extern uint32_t EPD_BS_PIN;
/**
* GPIO read and write
**/
#define DEV_Digital_Write(_pin, _value) nrf_gpio_pin_write(_pin, _value)
#define DEV_Digital_Read(_pin) nrf_gpio_pin_read(_pin)
/**
* delay x ms
**/
#define DEV_Delay_ms(__xms) nrf_delay_ms(__xms);
#define DEV_Delay_us(__xus) nrf_delay_us(__xus);
UBYTE DEV_Module_Init(void);
void DEV_Module_Exit(void);
void DEV_SPI_WriteByte(UBYTE value);
UBYTE DEV_SPI_ReadByte(void);
#endif

582
EPD/EPD_4in2.c Normal file
View File

@@ -0,0 +1,582 @@
/*****************************************************************************
* | File : EPD_4in2.c
* | Author : Waveshare team
* | Function : 4.2inch e-paper
* | Info :
*----------------
* | This version: V3.0
* | Date : 2019-06-13
* | Info :
* -----------------------------------------------------------------------------
* V3.0(2019-06-13):
* 1.Change:
* lut_vcomDC[] => EPD_4IN2_lut_vcomDC[]
* lut_ww[] => EPD_4IN2_lut_ww[]
* lut_bw[] => EPD_4IN2_lut_bw[]
* lut_wb[] => EPD_4IN2_lut_wb[]
* lut_bb[] => EPD_4IN2_lut_bb[]
* EPD_Reset() => EPD_4IN2_Reset()
* EPD_SendCommand() => EPD_4IN2_SendCommand()
* EPD_SendData() => EPD_4IN2_SendData()
* EPD_WaitUntilIdle() => EPD_4IN2_ReadBusy()
* EPD_SetFullReg() => EPD_4IN2_SetFullReg()
* EPD_SetPartReg() => EPD_4IN2_SetPartReg()
* EPD_TurnOnDisplay() => EPD_4IN2_TurnOnDisplay()
* EPD_Init() => EPD_4IN2_Init()
* EPD_Clear() => EPD_4IN2_Clear()
* EPD_Display() => EPD_4IN2_Display()
* EPD_Sleep() => EPD_4IN2_Sleep()
* 2.remove commands define:
* #define PANEL_SETTING 0x00
* #define POWER_SETTING 0x01
* #define POWER_OFF 0x02
* #define POWER_OFF_SEQUENCE_SETTING 0x03
* #define POWER_ON 0x04
* #define POWER_ON_MEASURE 0x05
* #define BOOSTER_SOFT_START 0x06
* #define DEEP_SLEEP 0x07
* #define DATA_START_TRANSMISSION_1 0x10
* #define DATA_STOP 0x11
* #define DISPLAY_REFRESH 0x12
* #define DATA_START_TRANSMISSION_2 0x13
* #define VCOM_LUT 0x20
* #define W2W_LUT 0x21
* #define B2W_LUT 0x22
* #define W2B_LUT 0x23
* #define B2B_LUT 0x24
* #define PLL_CONTROL 0x30
* #define TEMPERATURE_SENSOR_CALIBRATION 0x40
* #define TEMPERATURE_SENSOR_SELECTION 0x41
* #define TEMPERATURE_SENSOR_WRITE 0x42
* #define TEMPERATURE_SENSOR_READ 0x43
* #define VCOM_AND_DATA_INTERVAL_SETTING 0x50
* #define LOW_POWER_DETECTION 0x51
* #define TCON_SETTING 0x60
* #define RESOLUTION_SETTING 0x61
* #define GET_STATUS 0x71
* #define AUTO_MEASURE_VCOM 0x80
* #define READ_VCOM_VALUE 0x81
* #define VCM_DC_SETTING 0x82
* #define PARTIAL_WINDOW 0x90
* #define PARTIAL_IN 0x91
* #define PARTIAL_OUT 0x92
* #define PROGRAM_MODE 0xA0
* #define ACTIVE_PROGRAM 0xA1
* #define READ_OTP_DATA 0xA2
* #define POWER_SAVING 0xE3
* V2.0(2018-10-30):
* 1.Remove:ImageBuff[EPD_HEIGHT * EPD_WIDTH / 8]
* 2.Change:EPD_Display(UBYTE *Image)
* Need to pass parameters: pointer to cached data
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#include "EPD_4in2.h"
static const unsigned char EPD_4IN2_lut_vcom0[] = {
0x00, 0x08, 0x08, 0x00, 0x00, 0x02,
0x00, 0x0F, 0x0F, 0x00, 0x00, 0x01,
0x00, 0x08, 0x08, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
};
static const unsigned char EPD_4IN2_lut_ww[] = {
0x50, 0x08, 0x08, 0x00, 0x00, 0x02,
0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,
0xA0, 0x08, 0x08, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char EPD_4IN2_lut_bw[] = {
0x50, 0x08, 0x08, 0x00, 0x00, 0x02,
0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,
0xA0, 0x08, 0x08, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char EPD_4IN2_lut_wb[] = {
0xA0, 0x08, 0x08, 0x00, 0x00, 0x02,
0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,
0x50, 0x08, 0x08, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char EPD_4IN2_lut_bb[] = {
0x20, 0x08, 0x08, 0x00, 0x00, 0x02,
0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01,
0x10, 0x08, 0x08, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
/******************************partial screen update LUT*********************************/
const unsigned char EPD_4IN2_Partial_lut_vcom1[] ={
0x00, 0x01, 0x20, 0x01, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const unsigned char EPD_4IN2_Partial_lut_ww1[] ={
0x00, 0x01, 0x20, 0x01, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const unsigned char EPD_4IN2_Partial_lut_bw1[] ={
0x20, 0x01, 0x20, 0x01, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const unsigned char EPD_4IN2_Partial_lut_wb1[] ={
0x10, 0x01, 0x20, 0x01, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const unsigned char EPD_4IN2_Partial_lut_bb1[] ={
0x00, 0x01,0x20, 0x01, 0x00, 0x01,
0x00, 0x00,0x00, 0x00, 0x00, 0x00,
0x00, 0x00,0x00, 0x00, 0x00, 0x00,
0x00, 0x00,0x00, 0x00, 0x00, 0x00,
0x00, 0x00,0x00, 0x00, 0x00, 0x00,
0x00, 0x00,0x00, 0x00, 0x00, 0x00,
0x00, 0x00,0x00, 0x00, 0x00, 0x00,
};
/******************************gray*********************************/
//0~3 gray
const unsigned char EPD_4IN2_4Gray_lut_vcom[] =
{
0x00 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
0x60 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
0x00 ,0x14 ,0x00 ,0x00 ,0x00 ,0x01,
0x00 ,0x13 ,0x0A ,0x01 ,0x00 ,0x01,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
};
//R21
const unsigned char EPD_4IN2_4Gray_lut_ww[] ={
0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
0x10 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
0xA0 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
};
//R22H r
const unsigned char EPD_4IN2_4Gray_lut_bw[] ={
0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
0x99 ,0x0C ,0x01 ,0x03 ,0x04 ,0x01,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
};
//R23H w
const unsigned char EPD_4IN2_4Gray_lut_wb[] ={
0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
0x99 ,0x0B ,0x04 ,0x04 ,0x01 ,0x01,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
};
//R24H b
const unsigned char EPD_4IN2_4Gray_lut_bb[] ={
0x80 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
0x20 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
0x50 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
};
/******************************************************************************
function : Software reset
parameter:
******************************************************************************/
static void EPD_4IN2_Reset(void)
{
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(10);
DEV_Digital_Write(EPD_RST_PIN, 0);
DEV_Delay_ms(10);
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(10);
DEV_Digital_Write(EPD_RST_PIN, 0);
DEV_Delay_ms(10);
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(10);
DEV_Digital_Write(EPD_RST_PIN, 0);
DEV_Delay_ms(10);
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(10);
}
/******************************************************************************
function : send command
parameter:
Reg : Command register
******************************************************************************/
void EPD_4IN2_SendCommand(UBYTE Reg)
{
DEV_Digital_Write(EPD_DC_PIN, 0);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_SPI_WriteByte(Reg);
DEV_Digital_Write(EPD_CS_PIN, 1);
}
/******************************************************************************
function : send data
parameter:
Data : Write data
******************************************************************************/
void EPD_4IN2_SendData(UBYTE Data)
{
DEV_Digital_Write(EPD_DC_PIN, 1);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_SPI_WriteByte(Data);
DEV_Digital_Write(EPD_CS_PIN, 1);
}
/******************************************************************************
function : Wait until the busy_pin goes LOW
parameter:
******************************************************************************/
void EPD_4IN2_ReadBusy(void)
{
while(DEV_Digital_Read(EPD_BUSY_PIN) == 0) { //LOW: idle, HIGH: busy
DEV_Delay_ms(100);
}
}
/******************************************************************************
function : Turn On Display
parameter:
******************************************************************************/
static void EPD_4IN2_TurnOnDisplay(void)
{
EPD_4IN2_SendCommand(0x12);
DEV_Delay_ms(100);
EPD_4IN2_ReadBusy();
}
/******************************************************************************
function : set the look-up tables
parameter:
******************************************************************************/
static void EPD_4IN2_SetLut(void)
{
unsigned int count;
EPD_4IN2_SendCommand(0x20);
for(count=0;count<36;count++)
{EPD_4IN2_SendData(EPD_4IN2_lut_vcom0[count]);}
EPD_4IN2_SendCommand(0x21);
for(count=0;count<36;count++)
{EPD_4IN2_SendData(EPD_4IN2_lut_ww[count]);}
EPD_4IN2_SendCommand(0x22);
for(count=0;count<36;count++)
{EPD_4IN2_SendData(EPD_4IN2_lut_bw[count]);}
EPD_4IN2_SendCommand(0x23);
for(count=0;count<36;count++)
{EPD_4IN2_SendData(EPD_4IN2_lut_wb[count]);}
EPD_4IN2_SendCommand(0x24);
for(count=0;count<36;count++)
{EPD_4IN2_SendData(EPD_4IN2_lut_bb[count]);}
}
static void EPD_4IN2_Partial_SetLut(void)
{
unsigned int count;
EPD_4IN2_SendCommand(0x20);
for(count=0;count<44;count++)
{EPD_4IN2_SendData(EPD_4IN2_Partial_lut_vcom1[count]);}
EPD_4IN2_SendCommand(0x21);
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_Partial_lut_ww1[count]);}
EPD_4IN2_SendCommand(0x22);
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_Partial_lut_bw1[count]);}
EPD_4IN2_SendCommand(0x23);
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_Partial_lut_wb1[count]);}
EPD_4IN2_SendCommand(0x24);
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_Partial_lut_bb1[count]);}
}
//LUT download
static void EPD_4IN2_4Gray_lut(void)
{
unsigned int count;
{
EPD_4IN2_SendCommand(0x20); //vcom
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_vcom[count]);}
EPD_4IN2_SendCommand(0x21); //red not use
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_ww[count]);}
EPD_4IN2_SendCommand(0x22); //bw r
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_bw[count]);}
EPD_4IN2_SendCommand(0x23); //wb w
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_wb[count]);}
EPD_4IN2_SendCommand(0x24); //bb b
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_bb[count]);}
EPD_4IN2_SendCommand(0x25); //vcom
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_ww[count]);}
}
}
/******************************************************************************
function : Initialize the e-Paper register
parameter:
******************************************************************************/
void EPD_4IN2_Init(void)
{
EPD_4IN2_Reset();
EPD_4IN2_SendCommand(0x01); //POWER SETTING
EPD_4IN2_SendData (0x03);
EPD_4IN2_SendData (0x00);
EPD_4IN2_SendData (0x2b);
EPD_4IN2_SendData (0x2b);
EPD_4IN2_SendCommand(0x06); //boost soft start
EPD_4IN2_SendData (0x17); //A
EPD_4IN2_SendData (0x17); //B
EPD_4IN2_SendData (0x17); //C
EPD_4IN2_SendCommand(0x04);
EPD_4IN2_ReadBusy();
EPD_4IN2_SendCommand(0x00); //panel setting
EPD_4IN2_SendData(0xbf); //KW-bf KWR-2F BWROTP 0f BWOTP 1f
EPD_4IN2_SendCommand(0x30);
EPD_4IN2_SendData (0x3c); // 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
EPD_4IN2_SendCommand(0x61); //resolution setting
EPD_4IN2_SendData (0x01);
EPD_4IN2_SendData (0x90); //400
EPD_4IN2_SendData (0x01); //300
EPD_4IN2_SendData (0x2c);
EPD_4IN2_SendCommand(0x82); //vcom_DC setting
EPD_4IN2_SendData (0x12);
EPD_4IN2_SendCommand(0X50);
EPD_4IN2_SendData(0x97);
EPD_4IN2_SetLut();
}
void EPD_4IN2_Init_4Gray(void)
{
EPD_4IN2_Reset();
EPD_4IN2_SendCommand(0x01); //POWER SETTING
EPD_4IN2_SendData (0x03);
EPD_4IN2_SendData (0x00); //VGH=20V,VGL=-20V
EPD_4IN2_SendData (0x2b); //VDH=15V
EPD_4IN2_SendData (0x2b); //VDL=-15V
EPD_4IN2_SendData (0x13);
EPD_4IN2_SendCommand(0x06); //booster soft start
EPD_4IN2_SendData (0x17); //A
EPD_4IN2_SendData (0x17); //B
EPD_4IN2_SendData (0x17); //C
EPD_4IN2_SendCommand(0x04);
EPD_4IN2_ReadBusy();
EPD_4IN2_SendCommand(0x00); //panel setting
EPD_4IN2_SendData(0x3f); //KW-3f KWR-2F BWROTP 0f BWOTP 1f
EPD_4IN2_SendCommand(0x30); //PLL setting
EPD_4IN2_SendData (0x3c); //100hz
EPD_4IN2_SendCommand(0x61); //resolution setting
EPD_4IN2_SendData (0x01); //400
EPD_4IN2_SendData (0x90);
EPD_4IN2_SendData (0x01); //300
EPD_4IN2_SendData (0x2c);
EPD_4IN2_SendCommand(0x82); //vcom_DC setting
EPD_4IN2_SendData (0x12);
EPD_4IN2_SendCommand(0X50); //VCOM AND DATA INTERVAL SETTING
EPD_4IN2_SendData(0x97);
}
/******************************************************************************
function : Clear screen
parameter:
******************************************************************************/
void EPD_4IN2_Clear(void)
{
UWORD Width, Height;
Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
Height = EPD_4IN2_HEIGHT;
EPD_4IN2_SendCommand(0x92);
EPD_4IN2_SetLut();
EPD_4IN2_SendCommand(0x10);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_SendData(0xFF);
}
}
EPD_4IN2_SendCommand(0x13);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_SendData(0xFF);
}
}
EPD_4IN2_TurnOnDisplay();
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_4IN2_Display(UBYTE *Image)
{
UWORD Width, Height;
Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
Height = EPD_4IN2_HEIGHT;
EPD_4IN2_SendCommand(0x92);
EPD_4IN2_SetLut();
EPD_4IN2_SendCommand(0x13);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_SendData(Image[i + j * Width]);
}
}
EPD_4IN2_TurnOnDisplay();
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_4IN2_Display_Half(UBYTE *Image, UBYTE Region)
{
UWORD Width, Height;
Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
Height = EPD_4IN2_HEIGHT;
if(Region == 1){
EPD_4IN2_SendCommand(0x13);
for (UWORD j = 0; j < Height/2; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_SendData(Image[i + j * Width]);
}
}
}else if(Region == 2){
for (UWORD j = 0; j < Height/2; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_SendData(Image[i + j * Width]);
}
}
}
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_4IN2_UpdateDisplay(void)
{
EPD_4IN2_TurnOnDisplay();
}
/******************************************************************************
function : Enter sleep mode
parameter:
******************************************************************************/
void EPD_4IN2_Sleep(void)
{
EPD_4IN2_SendCommand(0x50); // DEEP_SLEEP
EPD_4IN2_SendData(0XF7);
EPD_4IN2_SendCommand(0x02); // POWER_OFF
EPD_4IN2_ReadBusy();
EPD_4IN2_SendCommand(0x07); // DEEP_SLEEP
EPD_4IN2_SendData(0XA5);
}

108
EPD/EPD_4in2.h Normal file
View File

@@ -0,0 +1,108 @@
/*****************************************************************************
* | File : EPD_4in2.h
* | Author : Waveshare team
* | Function : 4.2inch e-paper
* | Info :
*----------------
* | This version: V3.0
* | Date : 2019-06-13
* | Info :
* -----------------------------------------------------------------------------
* V3.0(2019-06-13):
* 1.Change:
* lut_vcomDC[] => EPD_4IN2_lut_vcomDC[]
* lut_ww[] => EPD_4IN2_lut_ww[]
* lut_bw[] => EPD_4IN2_lut_bw[]
* lut_wb[] => EPD_4IN2_lut_wb[]
* lut_bb[] => EPD_4IN2_lut_bb[]
* EPD_Reset() => EPD_4IN2_Reset()
* EPD_SendCommand() => EPD_4IN2_SendCommand()
* EPD_SendData() => EPD_4IN2_SendData()
* EPD_WaitUntilIdle() => EPD_4IN2_ReadBusy()
* EPD_SetFullReg() => EPD_4IN2_SetFullReg()
* EPD_SetPartReg() => EPD_4IN2_SetPartReg()
* EPD_TurnOnDisplay() => EPD_4IN2_TurnOnDisplay()
* EPD_Init() => EPD_4IN2_Init()
* EPD_Clear() => EPD_4IN2_Clear()
* EPD_Display() => EPD_4IN2_Display()
* EPD_Sleep() => EPD_4IN2_Sleep()
* 2.remove commands define:
* #define PANEL_SETTING 0x00
* #define POWER_SETTING 0x01
* #define POWER_OFF 0x02
* #define POWER_OFF_SEQUENCE_SETTING 0x03
* #define POWER_ON 0x04
* #define POWER_ON_MEASURE 0x05
* #define BOOSTER_SOFT_START 0x06
* #define DEEP_SLEEP 0x07
* #define DATA_START_TRANSMISSION_1 0x10
* #define DATA_STOP 0x11
* #define DISPLAY_REFRESH 0x12
* #define DATA_START_TRANSMISSION_2 0x13
* #define VCOM_LUT 0x20
* #define W2W_LUT 0x21
* #define B2W_LUT 0x22
* #define W2B_LUT 0x23
* #define B2B_LUT 0x24
* #define PLL_CONTROL 0x30
* #define TEMPERATURE_SENSOR_CALIBRATION 0x40
* #define TEMPERATURE_SENSOR_SELECTION 0x41
* #define TEMPERATURE_SENSOR_WRITE 0x42
* #define TEMPERATURE_SENSOR_READ 0x43
* #define VCOM_AND_DATA_INTERVAL_SETTING 0x50
* #define LOW_POWER_DETECTION 0x51
* #define TCON_SETTING 0x60
* #define RESOLUTION_SETTING 0x61
* #define GET_STATUS 0x71
* #define AUTO_MEASURE_VCOM 0x80
* #define READ_VCOM_VALUE 0x81
* #define VCM_DC_SETTING 0x82
* #define PARTIAL_WINDOW 0x90
* #define PARTIAL_IN 0x91
* #define PARTIAL_OUT 0x92
* #define PROGRAM_MODE 0xA0
* #define ACTIVE_PROGRAM 0xA1
* #define READ_OTP_DATA 0xA2
* #define POWER_SAVING 0xE3
* V2.0(2018-10-30):
* 1.Remove:ImageBuff[EPD_HEIGHT * EPD_WIDTH / 8]
* 2.Change:EPD_Display(UBYTE *Image)
* Need to pass parameters: pointer to cached data
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#ifndef _EPD_4IN2_H_
#define _EPD_4IN2_H_
#include "DEV_Config.h"
// Display resolution
#define EPD_4IN2_WIDTH 400
#define EPD_4IN2_HEIGHT 300
void EPD_4IN2_Init(void);
void EPD_4IN2_Clear(void);
void EPD_4IN2_Display(UBYTE *Image);
void EPD_4IN2_Sleep(void);
void EPD_4IN2_UpdateDisplay(void);
void EPD_4IN2_SendCommand(UBYTE Reg);
void EPD_4IN2_SendData(UBYTE Data);
#endif

621
EPD/EPD_4in2_V2.c Normal file
View File

@@ -0,0 +1,621 @@
/*****************************************************************************
* | File : EPD_4in2_V2.h
* | Author : Waveshare team
* | Function : 4.2inch e-paper V2
* | Info :
*----------------
* | This version: V1.0
* | Date : 2023-09-12
* | Info :
* -----------------------------------------------------------------------------
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#include "EPD_4in2_V2.h"
const unsigned char LUT_ALL[233]={
0x01, 0x0A, 0x1B, 0x0F, 0x03, 0x01, 0x01,
0x05, 0x0A, 0x01, 0x0A, 0x01, 0x01, 0x01,
0x05, 0x08, 0x03, 0x02, 0x04, 0x01, 0x01,
0x01, 0x04, 0x04, 0x02, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x0A, 0x1B, 0x0F, 0x03, 0x01, 0x01,
0x05, 0x4A, 0x01, 0x8A, 0x01, 0x01, 0x01,
0x05, 0x48, 0x03, 0x82, 0x84, 0x01, 0x01,
0x01, 0x84, 0x84, 0x82, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x0A, 0x1B, 0x8F, 0x03, 0x01, 0x01,
0x05, 0x4A, 0x01, 0x8A, 0x01, 0x01, 0x01,
0x05, 0x48, 0x83, 0x82, 0x04, 0x01, 0x01,
0x01, 0x04, 0x04, 0x02, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x8A, 0x1B, 0x8F, 0x03, 0x01, 0x01,
0x05, 0x4A, 0x01, 0x8A, 0x01, 0x01, 0x01,
0x05, 0x48, 0x83, 0x02, 0x04, 0x01, 0x01,
0x01, 0x04, 0x04, 0x02, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x8A, 0x9B, 0x8F, 0x03, 0x01, 0x01,
0x05, 0x4A, 0x01, 0x8A, 0x01, 0x01, 0x01,
0x05, 0x48, 0x03, 0x42, 0x04, 0x01, 0x01,
0x01, 0x04, 0x04, 0x42, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x07, 0x17, 0x41, 0xA8,
0x32, 0x30,
};
/******************************************************************************
function : Software reset
parameter:
******************************************************************************/
static void EPD_4IN2_V2_Reset(void)
{
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(100);
DEV_Digital_Write(EPD_RST_PIN, 0);
DEV_Delay_ms(2);
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(100);
}
/******************************************************************************
function : send command
parameter:
Reg : Command register
******************************************************************************/
void EPD_4IN2_V2_SendCommand(UBYTE Reg)
{
DEV_Digital_Write(EPD_DC_PIN, 0);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_SPI_WriteByte(Reg);
DEV_Digital_Write(EPD_CS_PIN, 1);
}
/******************************************************************************
function : send data
parameter:
Data : Write data
******************************************************************************/
void EPD_4IN2_V2_SendData(UBYTE Data)
{
DEV_Digital_Write(EPD_DC_PIN, 1);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_SPI_WriteByte(Data);
DEV_Digital_Write(EPD_CS_PIN, 1);
}
/******************************************************************************
function : Wait until the busy_pin goes LOW
parameter:
******************************************************************************/
void EPD_4IN2_V2_ReadBusy(void)
{
while(DEV_Digital_Read(EPD_BUSY_PIN) == 1) { //LOW: idle, HIGH: busy
DEV_Delay_ms(10);
}
}
/******************************************************************************
function : Turn On Display
parameter:
******************************************************************************/
static void EPD_4IN2_V2_TurnOnDisplay(void)
{
EPD_4IN2_V2_SendCommand(0x22);
EPD_4IN2_V2_SendData(0xF7);
EPD_4IN2_V2_SendCommand(0x20);
EPD_4IN2_V2_ReadBusy();
}
static void EPD_4IN2_V2_TurnOnDisplay_Fast(void)
{
EPD_4IN2_V2_SendCommand(0x22);
EPD_4IN2_V2_SendData(0xC7);
EPD_4IN2_V2_SendCommand(0x20);
EPD_4IN2_V2_ReadBusy();
}
static void EPD_4IN2_V2_TurnOnDisplay_Partial(void)
{
EPD_4IN2_V2_SendCommand(0x22);
EPD_4IN2_V2_SendData(0xFF);
EPD_4IN2_V2_SendCommand(0x20);
EPD_4IN2_V2_ReadBusy();
}
static void EPD_4IN2_V2_TurnOnDisplay_4Gray(void)
{
EPD_4IN2_V2_SendCommand(0x22);
EPD_4IN2_V2_SendData(0xCF);
EPD_4IN2_V2_SendCommand(0x20);
EPD_4IN2_V2_ReadBusy();
}
/******************************************************************************
function : Setting the display window
parameter:
******************************************************************************/
static void EPD_4IN2_V2_SetWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend)
{
EPD_4IN2_V2_SendCommand(0x44); // SET_RAM_X_ADDRESS_START_END_POSITION
EPD_4IN2_V2_SendData((Xstart>>3) & 0xFF);
EPD_4IN2_V2_SendData((Xend>>3) & 0xFF);
EPD_4IN2_V2_SendCommand(0x45); // SET_RAM_Y_ADDRESS_START_END_POSITION
EPD_4IN2_V2_SendData(Ystart & 0xFF);
EPD_4IN2_V2_SendData((Ystart >> 8) & 0xFF);
EPD_4IN2_V2_SendData(Yend & 0xFF);
EPD_4IN2_V2_SendData((Yend >> 8) & 0xFF);
}
/******************************************************************************
function : Set Cursor
parameter:
******************************************************************************/
static void EPD_4IN2_V2_SetCursor(UWORD Xstart, UWORD Ystart)
{
EPD_4IN2_V2_SendCommand(0x4E); // SET_RAM_X_ADDRESS_COUNTER
EPD_4IN2_V2_SendData(Xstart & 0xFF);
EPD_4IN2_V2_SendCommand(0x4F); // SET_RAM_Y_ADDRESS_COUNTER
EPD_4IN2_V2_SendData(Ystart & 0xFF);
EPD_4IN2_V2_SendData((Ystart >> 8) & 0xFF);
}
//LUT download
static void EPD_4IN2_V2_4Gray_lut(void)
{
unsigned char i;
//WS byte 0~152, the content of VS[nX-LUTm], TP[nX], RP[n], SR[nXY], FR[n] and XON[nXY]
EPD_4IN2_V2_SendCommand(0x32);
for(i=0;i<227;i++)
{
EPD_4IN2_V2_SendData(LUT_ALL[i]);
}
//WS byte 153, the content of Option for LUT end
EPD_4IN2_V2_SendCommand(0x3F);
EPD_4IN2_V2_SendData(LUT_ALL[i++]);
//WS byte 154, the content of gate leve
EPD_4IN2_V2_SendCommand(0x03);
EPD_4IN2_V2_SendData(LUT_ALL[i++]);//VGH
//WS byte 155~157, the content of source level
EPD_4IN2_V2_SendCommand(0x04);
EPD_4IN2_V2_SendData(LUT_ALL[i++]);//VSH1
EPD_4IN2_V2_SendData(LUT_ALL[i++]);//VSH2
EPD_4IN2_V2_SendData(LUT_ALL[i++]);//VSL
//WS byte 158, the content of VCOM level
EPD_4IN2_V2_SendCommand(0x2c);
EPD_4IN2_V2_SendData(LUT_ALL[i++]);//VCOM
}
/******************************************************************************
function : Initialize the e-Paper register
parameter:
******************************************************************************/
void EPD_4IN2_V2_Init(void)
{
EPD_4IN2_V2_Reset();
EPD_4IN2_V2_ReadBusy();
EPD_4IN2_V2_SendCommand(0x12); // soft reset
EPD_4IN2_V2_ReadBusy();
// EPD_4IN2_V2_SendCommand(0x01); //Driver output control
// EPD_4IN2_V2_SendData((EPD_4IN2_V2_HEIGHT-1)%256);
// EPD_4IN2_V2_SendData((EPD_4IN2_V2_HEIGHT-1)/256);
// EPD_4IN2_V2_SendData(0x00);
EPD_4IN2_V2_SendCommand(0x21); // Display update control
EPD_4IN2_V2_SendData(0x40);
EPD_4IN2_V2_SendData(0x00);
EPD_4IN2_V2_SendCommand(0x3C); //BorderWavefrom
EPD_4IN2_V2_SendData(0x05);
EPD_4IN2_V2_SendCommand(0x11); // data entry mode
EPD_4IN2_V2_SendData(0x03); // X-mode
EPD_4IN2_V2_SetWindows(0, 0, EPD_4IN2_V2_WIDTH-1, EPD_4IN2_V2_HEIGHT-1);
EPD_4IN2_V2_SetCursor(0, 0);
EPD_4IN2_V2_ReadBusy();
}
/******************************************************************************
function : Initialize Fast the e-Paper register
parameter:
******************************************************************************/
void EPD_4IN2_V2_Init_Fast(UBYTE Mode)
{
EPD_4IN2_V2_Reset();
EPD_4IN2_V2_ReadBusy();
EPD_4IN2_V2_SendCommand(0x12); // soft reset
EPD_4IN2_V2_ReadBusy();
EPD_4IN2_V2_SendCommand(0x21);
EPD_4IN2_V2_SendData(0x40);
EPD_4IN2_V2_SendData(0x00);
EPD_4IN2_V2_SendCommand(0x3C);
EPD_4IN2_V2_SendData(0x05);
if(Mode == Seconds_1_5S)
{
//1.5s
EPD_4IN2_V2_SendCommand(0x1A); // Write to temperature register
EPD_4IN2_V2_SendData(0x6E);
}
else if(Mode == Seconds_1S)
{
//1s
EPD_4IN2_V2_SendCommand(0x1A); // Write to temperature register
EPD_4IN2_V2_SendData(0x5A);
}
EPD_4IN2_V2_SendCommand(0x22); // Load temperature value
EPD_4IN2_V2_SendData(0x91);
EPD_4IN2_V2_SendCommand(0x20);
EPD_4IN2_V2_ReadBusy();
EPD_4IN2_V2_SendCommand(0x11); // data entry mode
EPD_4IN2_V2_SendData(0x03); // X-mode
EPD_4IN2_V2_SetWindows(0, 0, EPD_4IN2_V2_WIDTH-1, EPD_4IN2_V2_HEIGHT-1);
EPD_4IN2_V2_SetCursor(0, 0);
EPD_4IN2_V2_ReadBusy();
}
void EPD_4IN2_V2_Init_4Gray(void)
{
EPD_4IN2_V2_Reset();
EPD_4IN2_V2_SendCommand(0x12); //SWRESET
EPD_4IN2_V2_ReadBusy();
EPD_4IN2_V2_SendCommand(0x21);
EPD_4IN2_V2_SendData(0x00);
EPD_4IN2_V2_SendData(0x00);
EPD_4IN2_V2_SendCommand(0x3C);
EPD_4IN2_V2_SendData(0x03);
EPD_4IN2_V2_SendCommand(0x0C); //BTST
EPD_4IN2_V2_SendData(0x8B);//8B
EPD_4IN2_V2_SendData(0x9C);//9C
EPD_4IN2_V2_SendData(0xA4);//96 A4
EPD_4IN2_V2_SendData(0x0F);//0F
// EPD_4IN2_V2_SendCommand(0x01); // 驱动输出控制 drive output control
// EPD_4IN2_V2_SendData(0x2B); // Y 的低字节
// EPD_4IN2_V2_SendData(0x01); // Y 的高字节
// EPD_4IN2_V2_SendData(0x00);
EPD_4IN2_V2_4Gray_lut(); //LUT
EPD_4IN2_V2_SendCommand(0x11); // data entry mode
EPD_4IN2_V2_SendData(0x03); // X-mode
EPD_4IN2_V2_SetWindows(0, 0, EPD_4IN2_V2_WIDTH-1, EPD_4IN2_V2_HEIGHT-1);
EPD_4IN2_V2_SetCursor(0, 0);
}
/******************************************************************************
function : Clear screen
parameter:
******************************************************************************/
void EPD_4IN2_V2_Clear(void)
{
UWORD Width, Height;
Width = (EPD_4IN2_V2_WIDTH % 8 == 0)? (EPD_4IN2_V2_WIDTH / 8 ): (EPD_4IN2_V2_WIDTH / 8 + 1);
Height = EPD_4IN2_V2_HEIGHT;
EPD_4IN2_V2_SendCommand(0x24);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_V2_SendData(0xFF);
}
}
EPD_4IN2_V2_SendCommand(0x26);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_V2_SendData(0xFF);
}
}
EPD_4IN2_V2_TurnOnDisplay();
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_4IN2_V2_Display_Half(UBYTE *Image, UBYTE Region)
{
UWORD Width, Height;
Width = (EPD_4IN2_V2_WIDTH % 8 == 0)? (EPD_4IN2_V2_WIDTH / 8 ): (EPD_4IN2_V2_WIDTH / 8 + 1);
Height = EPD_4IN2_V2_HEIGHT;
if(Region == 1){
EPD_4IN2_V2_SendCommand(0x24);
for (UWORD j = 0; j < Height/2; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_V2_SendData(Image[i + j * Width]);
}
}
EPD_4IN2_V2_SendCommand(0x26);
for (UWORD j = 0; j < Height/2; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_V2_SendData(Image[i + j * Width]);
}
}
}
else if(Region == 2){
EPD_4IN2_V2_SendCommand(0x24);
for (UWORD j = 0; j < Height/2; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_V2_SendData(Image[i + j * Width]);
}
}
EPD_4IN2_V2_SendCommand(0x26);
for (UWORD j = 0; j < Height/2; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_V2_SendData(Image[i + j * Width]);
}
}
EPD_4IN2_V2_TurnOnDisplay();
}
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_4IN2_V2_Display(UBYTE *Image)
{
UWORD Width, Height;
Width = (EPD_4IN2_V2_WIDTH % 8 == 0)? (EPD_4IN2_V2_WIDTH / 8 ): (EPD_4IN2_V2_WIDTH / 8 + 1);
Height = EPD_4IN2_V2_HEIGHT;
EPD_4IN2_V2_SendCommand(0x24);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_V2_SendData(Image[i + j * Width]);
}
}
EPD_4IN2_V2_SendCommand(0x26);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_V2_SendData(Image[i + j * Width]);
}
}
EPD_4IN2_V2_TurnOnDisplay();
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and fast displays
parameter:
******************************************************************************/
void EPD_4IN2_V2_Display_Fast(UBYTE *Image)
{
UWORD Width, Height;
Width = (EPD_4IN2_V2_WIDTH % 8 == 0)? (EPD_4IN2_V2_WIDTH / 8 ): (EPD_4IN2_V2_WIDTH / 8 + 1);
Height = EPD_4IN2_V2_HEIGHT;
EPD_4IN2_V2_SendCommand(0x24);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_V2_SendData(Image[i + j * Width]);
}
}
EPD_4IN2_V2_SendCommand(0x26);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_V2_SendData(Image[i + j * Width]);
}
}
EPD_4IN2_V2_TurnOnDisplay_Fast();
}
void EPD_4IN2_V2_Display_4Gray(UBYTE *Image)
{
UDOUBLE i,j,k,m;
UBYTE temp1,temp2,temp3;
/****Color display description****
white gray2 gray1 black
0x10| 01 01 00 00
0x13| 01 00 01 00
*********************************/
EPD_4IN2_V2_SendCommand(0x24);
// EPD_4IN2_HEIGHT
// EPD_4IN2_WIDTH
for(m = 0; m<EPD_4IN2_V2_HEIGHT;m++)
for(i=0;i<EPD_4IN2_V2_WIDTH/8;i++)
{
temp3=0;
for(j=0;j<2;j++)
{
temp1 = Image[(m*(EPD_4IN2_V2_WIDTH/8)+i)*2+j];
for(k=0;k<2;k++)
{
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0)
temp3 |= 0x01;//white
else if(temp2 == 0x00)
temp3 |= 0x00; //black
else if(temp2 == 0x80)
temp3 |= 0x00; //gray1
else //0x40
temp3 |= 0x01; //gray2
temp3 <<= 1;
temp1 <<= 2;
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0) //white
temp3 |= 0x01;
else if(temp2 == 0x00) //black
temp3 |= 0x00;
else if(temp2 == 0x80)
temp3 |= 0x00; //gray1
else //0x40
temp3 |= 0x01; //gray2
if(j!=1 || k!=1)
temp3 <<= 1;
temp1 <<= 2;
}
}
EPD_4IN2_V2_SendData(temp3);
}
// new data
EPD_4IN2_V2_SendCommand(0x26);
for(m = 0; m<EPD_4IN2_V2_HEIGHT;m++)
for(i=0;i<EPD_4IN2_V2_WIDTH/8;i++)
{
temp3=0;
for(j=0;j<2;j++)
{
temp1 = Image[(m*(EPD_4IN2_V2_WIDTH/8)+i)*2+j];
for(k=0;k<2;k++)
{
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0)
temp3 |= 0x01;//white
else if(temp2 == 0x00)
temp3 |= 0x00; //black
else if(temp2 == 0x80)
temp3 |= 0x01; //gray1
else //0x40
temp3 |= 0x00; //gray2
temp3 <<= 1;
temp1 <<= 2;
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0) //white
temp3 |= 0x01;
else if(temp2 == 0x00) //black
temp3 |= 0x00;
else if(temp2 == 0x80)
temp3 |= 0x01; //gray1
else //0x40
temp3 |= 0x00; //gray2
if(j!=1 || k!=1)
temp3 <<= 1;
temp1 <<= 2;
}
}
EPD_4IN2_V2_SendData(temp3);
}
EPD_4IN2_V2_TurnOnDisplay_4Gray();
}
// Send partial data for partial refresh
void EPD_4IN2_V2_PartialDisplay(UBYTE *Image, UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend)
{
if((Xstart % 8 + Xend % 8 == 8 && Xstart % 8 > Xend % 8) || Xstart % 8 + Xend % 8 == 0 || (Xend - Xstart)%8 == 0)
{
Xstart = Xstart / 8 ;
Xend = Xend / 8;
}
else
{
Xstart = Xstart / 8 ;
Xend = Xend % 8 == 0 ? Xend / 8 : Xend / 8 + 1;
}
UWORD i, Width;
Width = Xend - Xstart;
UWORD IMAGE_COUNTER = Width * (Yend-Ystart);
Xend -= 1;
Yend -= 1;
EPD_4IN2_V2_SendCommand(0x3C); //BorderWavefrom,
EPD_4IN2_V2_SendData(0x80);
EPD_4IN2_V2_SendCommand(0x21);
EPD_4IN2_V2_SendData(0x00);
EPD_4IN2_V2_SendData(0x00);
EPD_4IN2_V2_SendCommand(0x3C);
EPD_4IN2_V2_SendData(0x80);
EPD_4IN2_V2_SendCommand(0x44); // set RAM x address start/end, in page 35
EPD_4IN2_V2_SendData(Xstart & 0xff); // RAM x address start at 00h;
EPD_4IN2_V2_SendData(Xend & 0xff); // RAM x address end at 0fh(15+1)*8->128
EPD_4IN2_V2_SendCommand(0x45); // set RAM y address start/end, in page 35
EPD_4IN2_V2_SendData(Ystart & 0xff); // RAM y address start at 0127h;
EPD_4IN2_V2_SendData((Ystart>>8) & 0x01); // RAM y address start at 0127h;
EPD_4IN2_V2_SendData(Yend & 0xff); // RAM y address end at 00h;
EPD_4IN2_V2_SendData((Yend>>8) & 0x01);
EPD_4IN2_V2_SendCommand(0x4E); // set RAM x address count to 0;
EPD_4IN2_V2_SendData(Xstart & 0xff);
EPD_4IN2_V2_SendCommand(0x4F); // set RAM y address count to 0X127;
EPD_4IN2_V2_SendData(Ystart & 0xff);
EPD_4IN2_V2_SendData((Ystart>>8) & 0x01);
EPD_4IN2_V2_SendCommand(0x24);
for (i = 0; i < IMAGE_COUNTER; i++) {
EPD_4IN2_V2_SendData(Image[i]);
}
EPD_4IN2_V2_TurnOnDisplay_Partial();
}
void EPD_4IN2_V2_UpdateDisplay(void)
{
EPD_4IN2_V2_TurnOnDisplay();
}
/******************************************************************************
function : Enter sleep mode
parameter:
******************************************************************************/
void EPD_4IN2_V2_Sleep(void)
{
EPD_4IN2_V2_SendCommand(0x10); // DEEP_SLEEP
EPD_4IN2_V2_SendData(0x01);
DEV_Delay_ms(200);
}

56
EPD/EPD_4in2_V2.h Normal file
View File

@@ -0,0 +1,56 @@
/*****************************************************************************
* | File : EPD_4in2_V2.h
* | Author : Waveshare team
* | Function : 4.2inch e-paper V2
* | Info :
*----------------
* | This version: V1.0
* | Date : 2023-09-12
* | Info :
* -----------------------------------------------------------------------------
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#ifndef _EPD_4IN2_V2_H_
#define _EPD_4IN2_V2_H_
#include "DEV_Config.h"
// Display resolution
#define EPD_4IN2_V2_WIDTH 400
#define EPD_4IN2_V2_HEIGHT 300
#define Seconds_1_5S 0
#define Seconds_1S 1
void EPD_4IN2_V2_Init(void);
void EPD_4IN2_V2_Init_Fast(UBYTE Mode);
void EPD_4IN2_V2_Init_4Gray(void);
void EPD_4IN2_V2_Clear(void);
void EPD_4IN2_V2_Display_Half(UBYTE *Image, UBYTE Region);
void EPD_4IN2_V2_Display(UBYTE *Image);
void EPD_4IN2_V2_Display_Fast(UBYTE *Image);
void EPD_4IN2_V2_Display_4Gray(UBYTE *Image);
void EPD_4IN2_V2_PartialDisplay(UBYTE *Image, UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend);
void EPD_4IN2_V2_Sleep(void);
void EPD_4IN2_V2_SendCommand(UBYTE Reg);
void EPD_4IN2_V2_SendData(UBYTE Data);
void EPD_4IN2_V2_UpdateDisplay(void);
#endif

221
EPD/EPD_4in2b_V2.c Normal file
View File

@@ -0,0 +1,221 @@
/*****************************************************************************
* | File : EPD_4in2b_V2.c
* | Author : Waveshare team
* | Function : 4.2inch e-paper b V2
* | Info :
*----------------
* | This version: V1.0
* | Date : 2020-11-27
* | Info :
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#include "EPD_4in2b_V2.h"
/******************************************************************************
function : Software reset
parameter:
******************************************************************************/
static void EPD_4IN2B_V2_Reset(void)
{
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(200);
DEV_Digital_Write(EPD_RST_PIN, 0);
DEV_Delay_ms(2);
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(200);
}
/******************************************************************************
function : send command
parameter:
Reg : Command register
******************************************************************************/
void EPD_4IN2B_V2_SendCommand(UBYTE Reg)
{
DEV_Digital_Write(EPD_DC_PIN, 0);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_SPI_WriteByte(Reg);
DEV_Digital_Write(EPD_CS_PIN, 1);
}
/******************************************************************************
function : send data
parameter:
Data : Write data
******************************************************************************/
void EPD_4IN2B_V2_SendData(UBYTE Data)
{
DEV_Digital_Write(EPD_DC_PIN, 1);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_SPI_WriteByte(Data);
DEV_Digital_Write(EPD_CS_PIN, 1);
}
/******************************************************************************
function : Wait until the busy_pin goes LOW
parameter:
******************************************************************************/
void EPD_4IN2B_V2_ReadBusy(void)
{
do{
EPD_4IN2B_V2_SendCommand(0x71);
DEV_Delay_ms(50);
}while(!(DEV_Digital_Read(EPD_BUSY_PIN)));
DEV_Delay_ms(50);
}
/******************************************************************************
function : Turn On Display
parameter:
******************************************************************************/
static void EPD_4IN2B_V2_TurnOnDisplay(void)
{
EPD_4IN2B_V2_SendCommand(0x12); // DISPLAY_REFRESH
DEV_Delay_ms(100);
EPD_4IN2B_V2_ReadBusy();
}
/******************************************************************************
function : Initialize the e-Paper register
parameter:
******************************************************************************/
void EPD_4IN2B_V2_Init(void)
{
EPD_4IN2B_V2_Reset();
EPD_4IN2B_V2_SendCommand(0x04);
EPD_4IN2B_V2_ReadBusy();
EPD_4IN2B_V2_SendCommand(0x00);
EPD_4IN2B_V2_SendData(0x0f);
}
/******************************************************************************
function : Clear screen
parameter:
******************************************************************************/
void EPD_4IN2B_V2_Clear(void)
{
UWORD Width, Height;
Width = (EPD_4IN2B_V2_WIDTH % 8 == 0)? (EPD_4IN2B_V2_WIDTH / 8 ): (EPD_4IN2B_V2_WIDTH / 8 + 1);
Height = EPD_4IN2B_V2_HEIGHT;
EPD_4IN2B_V2_SendCommand(0x10);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2B_V2_SendData(0xFF);
}
}
EPD_4IN2B_V2_SendCommand(0x13);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2B_V2_SendData(0xFF);
}
}
EPD_4IN2B_V2_TurnOnDisplay();
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_4IN2B_V2_Display(const UBYTE *blackimage, const UBYTE *ryimage)
{
UWORD Width, Height;
Width = (EPD_4IN2B_V2_WIDTH % 8 == 0)? (EPD_4IN2B_V2_WIDTH / 8 ): (EPD_4IN2B_V2_WIDTH / 8 + 1);
Height = EPD_4IN2B_V2_HEIGHT;
EPD_4IN2B_V2_SendCommand(0x10);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2B_V2_SendData(blackimage[i + j * Width]);
}
}
EPD_4IN2B_V2_SendCommand(0x13);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2B_V2_SendData(ryimage[i + j * Width]);
}
}
EPD_4IN2B_V2_TurnOnDisplay();
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_4IN2B_V2_Display_Half(const UBYTE *blackimage, UBYTE Region)
{
UWORD Width, Height;
Width = (EPD_4IN2B_V2_WIDTH % 8 == 0)? (EPD_4IN2B_V2_WIDTH / 8 ): (EPD_4IN2B_V2_WIDTH / 8 + 1);
Height = EPD_4IN2B_V2_HEIGHT;
if(Region == 1){
EPD_4IN2B_V2_SendCommand(0x10);
for (UWORD j = 0; j < Height/2; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2B_V2_SendData(blackimage[i + j * Width]);
}
}
}else if(Region == 2){
for (UWORD j = 0; j < Height/2; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2B_V2_SendData(blackimage[i + j * Width]);
}
}
}else if(Region == 3){
EPD_4IN2B_V2_SendCommand(0x13);
for (UWORD j = 0; j < Height/2; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2B_V2_SendData(blackimage[i + j * Width]);
}
}
}else if(Region == 4){
for (UWORD j = 0; j < Height/2; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2B_V2_SendData(blackimage[i + j * Width]);
}
}
}
}
void EPD_4IN2B_V2_UpdateDisplay(void)
{
EPD_4IN2B_V2_TurnOnDisplay();
}
/******************************************************************************
function : Enter sleep mode
parameter:
******************************************************************************/
void EPD_4IN2B_V2_Sleep(void)
{
EPD_4IN2B_V2_SendCommand(0X50);
EPD_4IN2B_V2_SendData(0xf7); //border floating
EPD_4IN2B_V2_SendCommand(0X02); //power off
EPD_4IN2B_V2_ReadBusy(); //waiting for the electronic paper IC to release the idle signal
EPD_4IN2B_V2_SendCommand(0X07); //deep sleep
EPD_4IN2B_V2_SendData(0xA5);
}

47
EPD/EPD_4in2b_V2.h Normal file
View File

@@ -0,0 +1,47 @@
/*****************************************************************************
* | File : EPD_4in2b_V2.h
* | Author : Waveshare team
* | Function : 4.2inch e-paper b V2
* | Info :
*----------------
* | This version: V1.0
* | Date : 2020-11-27
* | Info :
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#ifndef __EPD_4IN2B_V2_H_
#define __EPD_4IN2B_V2_H_
#include "DEV_Config.h"
// Display resolution
#define EPD_4IN2B_V2_WIDTH 400
#define EPD_4IN2B_V2_HEIGHT 300
void EPD_4IN2B_V2_Init(void);
void EPD_4IN2B_V2_Clear(void);
void EPD_4IN2B_V2_Display(const UBYTE *blackimage, const UBYTE *ryimage);
void EPD_4IN2B_V2_Sleep(void);
void EPD_4IN2B_V2_Display_Half(const UBYTE *blackimage, UBYTE Region);
void EPD_4IN2B_V2_UpdateDisplay(void);
void EPD_4IN2B_V2_SendCommand(UBYTE Reg);
void EPD_4IN2B_V2_SendData(UBYTE Data);
#endif

302
EPD/EPD_ble.c Normal file
View File

@@ -0,0 +1,302 @@
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#include <string.h>
#include "nordic_common.h"
#include "ble_srv_common.h"
#include "nrf_log.h"
#include "EPD_4in2.h"
#include "EPD_4in2_V2.h"
#include "EPD_4in2b_V2.h"
#include "EPD_ble.h"
#define BLE_EPD_BASE_UUID {{0XEC, 0X5A, 0X67, 0X1C, 0XC1, 0XB6, 0X46, 0XFB, \
0X8D, 0X91, 0X28, 0XD8, 0X22, 0X36, 0X75, 0X62}}
#define BLE_UUID_EPD_SERVICE 0x0001
#define BLE_UUID_EPD_CHARACTERISTIC 0x0002
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
/** EPD drivers */
static epd_driver_t epd_drivers[] = {
{EPD_DRIVER_4IN2, EPD_4IN2_Init, EPD_4IN2_Clear,
EPD_4IN2_SendCommand, EPD_4IN2_SendData,
EPD_4IN2_UpdateDisplay, EPD_4IN2_Sleep},
{EPD_DRIVER_4IN2_V2, EPD_4IN2_V2_Init, EPD_4IN2_V2_Clear,
EPD_4IN2_V2_SendCommand, EPD_4IN2_V2_SendData,
EPD_4IN2_V2_UpdateDisplay, EPD_4IN2_V2_Sleep},
{EPD_DRIVER_4IN2B_V2, EPD_4IN2B_V2_Init, EPD_4IN2B_V2_Clear,
EPD_4IN2B_V2_SendCommand, EPD_4IN2B_V2_SendData,
EPD_4IN2B_V2_UpdateDisplay, EPD_4IN2B_V2_Sleep},
};
/**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the S110 SoftDevice.
*
* @param[in] p_epd EPD Service structure.
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
*/
static void on_connect(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
{
p_epd->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
DEV_Module_Init();
}
/**@brief Function for handling the @ref BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice.
*
* @param[in] p_epd EPD Service structure.
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
*/
static void on_disconnect(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
{
UNUSED_PARAMETER(p_ble_evt);
p_epd->conn_handle = BLE_CONN_HANDLE_INVALID;
DEV_Module_Exit();
}
static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t length)
{
if (p_data == NULL || length <= 0) return;
NRF_LOG_PRINTF("[EPD]: CMD=0x%02x, LEN=%d\n", p_data[0], length);
switch (p_data[0])
{
case EPD_CMD_SET_PINS:
if (length < 8) return;
NRF_LOG_PRINTF("[EPD]: MOSI=0x%02x SCLK=0x%02x CS=0x%02x DC=0x%02x RST=0x%02x BUSY=0x%02x BS=0x%02x\n",
p_data[1], p_data[2], p_data[3], p_data[4], p_data[5], p_data[6], p_data[7]);
EPD_MOSI_PIN = p_data[1];
EPD_SCLK_PIN = p_data[2];
EPD_CS_PIN = p_data[3];
EPD_DC_PIN = p_data[4];
EPD_RST_PIN = p_data[5];
EPD_BUSY_PIN = p_data[6];
EPD_BS_PIN = p_data[7];
DEV_Module_Exit();
DEV_Module_Init();
break;
case EPD_CMD_INIT:
if (length > 1)
{
for (uint8_t i = 0; i < ARRAY_SIZE(epd_drivers); i++)
{
if (epd_drivers[i].id == p_data[1])
{
p_epd->driver = &epd_drivers[i];
}
}
}
if (p_epd->driver == NULL) p_epd->driver= &epd_drivers[0];
NRF_LOG_PRINTF("[EPD]: DRIVER=%d\n", p_epd->driver->id);
p_epd->driver->init();
break;
case EPD_CMD_CLEAR:
p_epd->driver->clear();
break;
case EPD_CMD_SEND_COMMAND:
if (length < 2) return;
p_epd->driver->send_command(p_data[1]);
break;
case EPD_CMD_SEND_DATA:
for (UWORD i = 0; i < length - 1; i++)
{
p_epd->driver->send_data(p_data[i + 1]);
}
break;
case EPD_CMD_DISPLAY:
p_epd->driver->display();
DEV_Delay_ms(500);
break;
case EPD_CMD_SLEEP:
p_epd->driver->sleep();
DEV_Delay_ms(200);
break;
default:
break;
}
}
/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the S110 SoftDevice.
*
* @param[in] p_epd EPD Service structure.
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
*/
static void on_write(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
{
ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
if (
(p_evt_write->handle == p_epd->char_handles.cccd_handle)
&&
(p_evt_write->len == 2)
)
{
if (ble_srv_is_notification_enabled(p_evt_write->data))
{
p_epd->is_notification_enabled = true;
}
else
{
p_epd->is_notification_enabled = false;
}
}
else if (p_evt_write->handle == p_epd->char_handles.value_handle)
{
epd_service_process(p_epd, p_evt_write->data, p_evt_write->len);
}
else
{
// Do Nothing. This event is not relevant for this service.
}
}
void ble_epd_on_ble_evt(ble_epd_t * p_epd, ble_evt_t * p_ble_evt)
{
if ((p_epd == NULL) || (p_ble_evt == NULL))
{
return;
}
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
on_connect(p_epd, p_ble_evt);
break;
case BLE_GAP_EVT_DISCONNECTED:
on_disconnect(p_epd, p_ble_evt);
break;
case BLE_GATTS_EVT_WRITE:
on_write(p_epd, p_ble_evt);
break;
default:
// No implementation needed.
break;
}
}
static uint32_t epd_service_init(ble_epd_t * p_epd)
{
ble_uuid128_t base_uuid = BLE_EPD_BASE_UUID;
ble_uuid_t ble_uuid;
uint32_t err_code;
err_code = sd_ble_uuid_vs_add(&base_uuid, &ble_uuid.type);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
ble_uuid.uuid = BLE_UUID_EPD_SERVICE;
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
&ble_uuid,
&p_epd->service_handle);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
ble_gatts_char_md_t char_md;
ble_gatts_attr_md_t cccd_md;
ble_gatts_attr_t attr_char_value;
ble_uuid_t char_uuid;
ble_gatts_attr_md_t attr_md;
memset(&cccd_md, 0, sizeof(cccd_md));
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.read = 1;
char_md.char_props.notify = 1;
char_md.char_props.write = 1;
char_md.char_props.write_wo_resp = 1;
char_md.p_cccd_md = &cccd_md;
char_uuid.type = ble_uuid.type;
char_uuid.uuid = BLE_UUID_EPD_CHARACTERISTIC;
memset(&attr_md, 0, sizeof(attr_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
attr_md.vloc = BLE_GATTS_VLOC_STACK;
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid = &char_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len = sizeof(uint8_t);
attr_char_value.init_offs = 0;
attr_char_value.max_len = BLE_EPD_MAX_DATA_LEN;
err_code = sd_ble_gatts_characteristic_add(p_epd->service_handle,
&char_md,
&attr_char_value,
&p_epd->char_handles);
return err_code;
}
uint32_t ble_epd_init(ble_epd_t * p_epd)
{
if (p_epd == NULL)
{
return NRF_ERROR_NULL;
}
// Initialize the service structure.
p_epd->conn_handle = BLE_CONN_HANDLE_INVALID;
p_epd->is_notification_enabled = false;
// Add the service.
return epd_service_init(p_epd);
}
uint32_t ble_epd_string_send(ble_epd_t * p_epd, uint8_t * p_string, uint16_t length)
{
ble_gatts_hvx_params_t hvx_params;
if (p_epd == NULL)
{
return NRF_ERROR_NULL;
}
if ((p_epd->conn_handle == BLE_CONN_HANDLE_INVALID) || (!p_epd->is_notification_enabled))
{
return NRF_ERROR_INVALID_STATE;
}
if (length > BLE_EPD_MAX_DATA_LEN)
{
return NRF_ERROR_INVALID_PARAM;
}
memset(&hvx_params, 0, sizeof(hvx_params));
hvx_params.handle = p_epd->char_handles.value_handle;
hvx_params.p_data = p_string;
hvx_params.p_len = &length;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
return sd_ble_gatts_hvx(p_epd->conn_handle, &hvx_params);
}

136
EPD/EPD_ble.h Normal file
View File

@@ -0,0 +1,136 @@
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
/**@file
*
* @defgroup ble_sdk_srv_nus Nordic UART Service
* @{
* @ingroup ble_sdk_srv
* @brief Nordic UART Service implementation.
*
* @details The Nordic UART Service is a simple GATT-based service with TX and RX characteristics.
* Data received from the peer is passed to the application, and the data received
* from the application of this service is sent to the peer as Handle Value
* Notifications. This module demonstrates how to implement a custom GATT-based
* service and characteristics using the S110 SoftDevice. The service
* is used by the application to send and receive ASCII text strings to and from the
* peer.
*
* @note The application must propagate S110 SoftDevice events to the Nordic UART Service module
* by calling the ble_nus_on_ble_evt() function from the ble_stack_handler callback.
*/
#ifndef EPD_BLE_H__
#define EPD_BLE_H__
#include "ble.h"
#include "ble_srv_common.h"
#include <stdint.h>
#include <stdbool.h>
#include "DEV_Config.h"
#define BLE_EPD_MAX_DATA_LEN (GATT_MTU_SIZE_DEFAULT - 3) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
enum EPD_CMDS
{
EPD_CMD_SET_PINS,
EPD_CMD_INIT,
EPD_CMD_CLEAR,
EPD_CMD_SEND_COMMAND,
EPD_CMD_SEND_DATA,
EPD_CMD_DISPLAY,
EPD_CMD_SLEEP,
};
/* Forward declaration of the epd_driver_t type. */
typedef struct epd_driver_s epd_driver_t;
/**< epd driver DIs. */
enum EPD_DRIVER_IDS
{
EPD_DRIVER_4IN2 = 1,
EPD_DRIVER_4IN2_V2,
EPD_DRIVER_4IN2B_V2,
};
/**@brief EPD driver structure.
*
* @details This structure contains epd driver functions.
*/
struct epd_driver_s
{
uint8_t id; /**< driver ID. */
void (*init)(void); /**< Initialize the e-Paper register */
void (*clear)(void); /**< Clear screen */
void (*send_command)(UBYTE Reg); /**< send command */
void (*send_data)(UBYTE Data); /**< send data */
void (*display)(void); /**< Sends the image buffer in RAM to e-Paper and displays */
void (*sleep)(void); /**< Enter sleep mode */
};
/* Forward declaration of the ble_epd_t type. */
typedef struct ble_epd_s ble_epd_t;
/**@brief EPD Service structure.
*
* @details This structure contains status information related to the service.
*/
struct ble_epd_s
{
uint8_t uuid_type; /**< UUID type for EPD Service Base UUID. */
uint16_t service_handle; /**< Handle of EPD Service (as provided by the S110 SoftDevice). */
ble_gatts_char_handles_t char_handles; /**< Handles related to the EPD characteristic (as provided by the S110 SoftDevice). */
uint16_t conn_handle; /**< Handle of the current connection (as provided by the S110 SoftDevice). BLE_CONN_HANDLE_INVALID if not in a connection. */
bool is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/
epd_driver_t *driver; /**< current EPD driver */
};
/**@brief Function for initializing the EPD Service.
*
* @param[out] p_epd EPD Service structure. This structure must be supplied
* by the application. It is initialized by this function and will
* later be used to identify this particular service instance.
* @param[in] p_epd_init Information needed to initialize the service.
*
* @retval NRF_SUCCESS If the service was successfully initialized. Otherwise, an error code is returned.
* @retval NRF_ERROR_NULL If either of the pointers p_epd or p_epd_init is NULL.
*/
uint32_t ble_epd_init(ble_epd_t * p_epd);
/**@brief Function for handling the EPD Service's BLE events.
*
* @details The EPD Service expects the application to call this function each time an
* event is received from the S110 SoftDevice. This function processes the event if it
* is relevant and calls the EPD Service event handler of the
* application if necessary.
*
* @param[in] p_epd EPD Service structure.
* @param[in] p_ble_evt Event received from the S110 SoftDevice.
*/
void ble_epd_on_ble_evt(ble_epd_t * p_epd, ble_evt_t * p_ble_evt);
/**@brief Function for sending a string to the peer.
*
* @details This function sends the input string as an RX characteristic notification to the
* peer.
*
* @param[in] p_epd Pointer to the EPD Service structure.
* @param[in] p_string String to be sent.
* @param[in] length Length of the string.
*
* @retval NRF_SUCCESS If the string was sent successfully. Otherwise, an error code is returned.
*/
uint32_t ble_epd_string_send(ble_epd_t * p_epd, uint8_t * p_string, uint16_t length);
#endif // EPD_BLE_H__
/** @} */