Files
readguy/src/guy_epaper/guy_370a/guy_370a.cpp
2023-11-12 04:08:29 +08:00

187 lines
6.9 KiB
C++

/******************** F r i e n d s h i p E n d e r ********************
* 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
* 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
* @file guy_370a.cpp
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @brief 3.7英寸墨水屏 驱动库函数
* @version 1.0
* @date 2023-09-21
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
*
* Apache License, Version 2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include "guy_370a.h"
#ifdef READGUY_DEV_370A
namespace guydev_370A{
static const PROGMEM unsigned char lut_1Grey_GC[] ={
0x2A,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//1
0x05,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//2
0x2A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//3
0x05,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//4
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//5
0x00,0x02,0x03,0x0A,0x00,0x02,0x06,0x0A,0x05,0x00
};
static const PROGMEM unsigned char lut_1Grey_A2[] ={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //1
0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //2
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //3
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //4
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //5
0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00
};
int drv::Init(void) {
if(sleeping) {
Reset();
sleeping=false;
part_mode=false;
}
BeginTransfer();
guy_epdCmd(0x12); DelayMs(300); //Power on display
guy_epdCmd(0x46); guy_epdParam(0xF7); guy_epdBusy(20);
guy_epdCmd(0x47); guy_epdParam(0xF7); guy_epdBusy(20);
guy_epdCmd(0x01); guy_epdParam(0xDF); guy_epdParam(0x01); guy_epdParam(0x00); // setting gaet number
guy_epdCmd(0x03); guy_epdParam(0x00); // set gate voltage
guy_epdCmd(0x04); guy_epdParam(0x41); guy_epdParam(0xA8); guy_epdParam(0x32); // set source voltage
guy_epdCmd(0x11); guy_epdParam(0x03); // set data entry sequence
guy_epdCmd(0x3C); guy_epdParam(0x01); // set border
guy_epdCmd(0x0C); // set booster strength
guy_epdParam(0xAE); guy_epdParam(0xC7); guy_epdParam(0xC3); guy_epdParam(0xC0); guy_epdParam(0xC0);
guy_epdCmd(0x18); guy_epdParam(0x80); // set internal sensor on
guy_epdCmd(0x2C); guy_epdParam(0x44); // set vcom value
guy_epdCmd(0x37); // set display option, these setting turn on previous function
guy_epdParam(0x00);
for(int i=0;i<4;i++) guy_epdParam(0xff);
guy_epdParam(0x4f);
for(int i=0;i<4;i++) guy_epdParam(0xff);
guy_epdCmd(0x44); // setting X direction start/end position of RAM
guy_epdParam(0x00); guy_epdParam(0x00); guy_epdParam(0x17); guy_epdParam(0x01);
guy_epdCmd(0x45); // setting Y direction start/end position of RAM
guy_epdParam(0x00); guy_epdParam(0x00); guy_epdParam(0xDF); guy_epdParam(0x01);
guy_epdCmd(0x22); guy_epdParam(0xCF); // Display Update Control 2
EndTransfer();
return 0;
}
//以下代码均为我 FriendshipEnder 原创, 呵呵哒~~
void drv::Load_LUT(unsigned char mode) {
unsigned int i;
guy_epdCmd(0x32);
for (i = 0; i < 60; i++) {
if(mode == 1)
guy_epdParam(pgm_read_byte(lut_1Grey_GC+i));
else if(mode == 0){
if(20==i && greyScaling<8) guy_epdParam(0x03);
else if(53==i && greyScaling<3) guy_epdParam(greyScaling);
else if(53==i && greyScaling==15) guy_epdParam(5);
else guy_epdParam(pgm_read_byte(lut_1Grey_A2+i));
}
}
for (i = 0; i < 45; i++) {
if(i<40) guy_epdParam(0x00);
else guy_epdParam(0x22);
}
}
void drv::drv_init(){ //初始化屏幕
sleeping = 1;
Init();
sleeping = 1;
part_mode=0;
//drv_color(0xff);
}
void drv::drv_fullpart(bool part){ //切换慢刷/快刷功能
if(lastRefresh || sleeping) return;
if(!part) {
greyScaling=15; //恢复默认的灰度模式
BeginTransfer();
guy_epdCmd(0x04); // set source voltage
guy_epdParam(0x41); guy_epdParam(0xA8); guy_epdParam(0x32);
EndTransfer();
}
part_mode=part;
}
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
if(m&1){//stage 1
if(lastRefresh) drv_dispWriter(f,2);
if(sleeping) Init();
BeginTransfer();
guy_epdCmd(0x4E); guy_epdParam(0x00); guy_epdParam(0x00);
guy_epdCmd(0x4F); guy_epdParam(0x00); guy_epdParam(0x00);
guy_epdCmd(0x24);
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
SpiTransfer(f(i)); //按照给定的RAM写入数据
if(!part_mode) {
guy_epdCmd(0x26);
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
SpiTransfer(f(i)); //按照给定的RAM写入数据
}
Load_LUT(!part_mode);
guy_epdCmd(0x20);
EndTransfer();
lastRefresh=millis();
}
if(m&2){//stage 2
uint32_t ms=millis()-lastRefresh;
uint32_t u=part_mode?500:1300;
if(ms<u) guy_epdBusy(u-ms);
lastRefresh=0;
}
//guy_epdBusy(part_mode?500:1300);
}
void drv::drv_sleep() { //开始屏幕睡眠
if(RST_PIN>=0){
BeginTransfer();
guy_epdCmd(0X10); //deep sleep
guy_epdParam(0x03);
EndTransfer();
}
sleeping = true;
part_mode=0;
}
void drv::drv_setDepth(uint8_t i){ //设置显示颜色深度, 不支持的话什么都不做
if(i<=0 || i>15) i=15; //形参 无所谓随便更改!
greyScaling=i;
if(i>7) i-=7;
// Depth: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 >=15
//VSH(V): 2.4 3.6 4.7 5.6 6.4 7.3 8.1 9.0 9.8 10.7 11.6 12.4 13.3 14.1 15.0
//HEX : 0x8E,0x9A,0xA5,0xAE,0xB6,0xBF,0xC7,0x23,0x27,0x2C,0x30,0x34,0x38,0x3D,0x41
static const uint8_t dep[]={0x8E,0x9A,0xA5,0xAE,0xB6,0xBF,0xC7,0x23,0x27,0x2C,0x30,0x34,0x38,0x3D};
BeginTransfer();
guy_epdCmd(0x04); // set source voltage
if(greyScaling==15){ guy_epdParam(0x41); guy_epdParam(0xA8); }
else{
guy_epdParam(dep[i+6]); // VSH1,default is 0x41 (15.0V)
guy_epdParam(dep[i-1]); // VSH2,default is 0xA8 (5.0V)
}
guy_epdParam(0x32);
EndTransfer();
part_mode=1;
}
}
#endif /* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */