AMEPD Active Matrix Electrophoretic Display, active matrix electrophoretic display.
It is the screen of electronic paper books, and the debugging effect is similar to that of my Kindle.
screen parameters
Screen IC is SSD1680
122*250, single bit control, 1 is white, 0 is black
Progressive refresh, one byte 8bit, control horizontal 8 pixels
Built-in temperature sensor (IIC interface, not used this time)
Built-in OTP (10Byte, not used this time)
The screen controller is On-Chip package
SPI rate setting 4M is enough
Show Effect Features
The refresh rate is low, and the data is updated in seconds
Updating a piece of data alone may cause afterimages.
Update the entire screen data, there will be a lot of flickering fluctuations
Power failure, hardware reset, and software reset will not affect the display, but the configuration needs to be re-sent until the next time new display data is written.
Debugging Notes
The logic communication voltage 2 of the whole screen is 3.3v.
spi is mode 0, clk is idle low, sampled on the first rising edge
BSI pin: configured as 3-wire 9data SPI (H) or 4-wire SPI communication mode (L) by pulling high and low
CS chip select pin: low effective, can be read and written when pulled low
DC pin: data/command indication pin. (L, command; H, write data)
BUSY pin: When the screen IC refreshes data or resets, it outputs high: it does not respond to external read and write operations at this time. Pay special attention to this in the reading and writing logic of the screen. (idle low, busy high)
RST pin: low level reset, keep high during operation
VGL, VGH pins: the bias voltage required for the screen to flip the liquid crystal particles, software configurable, 16-20v. Through its own GDR and RESE and peripheral circuits, it forms a boost circuit
SPI communication timing
4-Wire SPI
3-Wire 9Bit SPI
code demo
register configuration
static void my_amepd_RegInit(void)
{
AMEPD_SSD1680_WriteCmd(0x12); // SW Reset
my_sleep(20);
my_amepd_ReadBusy(); // wait busy
my_test_cli_echo("my_amepd_RegInit 0x12 \r\n");
AMEPD_SSD1680_WriteCmd(0x01);
AMEPD_SSD1680_WriteData(0xF9);
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteCmd(0x11); // data enter mode
AMEPD_SSD1680_WriteData(0x01);
AMEPD_SSD1680_WriteCmd(0x44); // set RAM x address
AMEPD_SSD1680_WriteData(0x00); // set x start, range: 0-15
AMEPD_SSD1680_WriteData(0x0F); // set x end
AMEPD_SSD1680_WriteCmd(0x45); // set RAM y address
AMEPD_SSD1680_WriteData(0xF9); // RAM y address start, range: 0-249
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteData(0x00); // RAM y address end
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteCmd(0x3C); // Border
AMEPD_SSD1680_WriteData(0x05);
AMEPD_SSD1680_WriteCmd(0x21); // Display update control
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteData(0x80); // S8-S167 for 1675 type panel
// use internal temperature sernsor
AMEPD_SSD1680_WriteCmd(0x18);
AMEPD_SSD1680_WriteData(0x80);
my_amepd_ReadBusy(); // wait busy
my_test_cli_echo("my_amepd_RegInit 0x18 \r\n");
}
set display coordinates
static void my_amepd_SetPosition(int x_start, int x_end, int y_start, int y_end)
{
my_test_cli_echo("%d \r\n", x_start);
my_test_cli_echo("%d \r\n", x_end);
my_test_cli_echo("%d \r\n", y_start);
my_test_cli_echo("%d \r\n", y_end);
my_amepd_RegInit();
my_test_cli_echo("my_amepd_SetPosition X \r\n");
AMEPD_SSD1680_WriteCmd(0x44);
AMEPD_SSD1680_WriteData(x_start);
AMEPD_SSD1680_WriteData(x_end);
AMEPD_SSD1680_WriteCmd(0x45);
AMEPD_SSD1680_WriteData(y_start);
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteData(y_end);
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteCmd(0x4E);
AMEPD_SSD1680_WriteData(x_start);
AMEPD_SSD1680_WriteCmd(0x4F);
AMEPD_SSD1680_WriteData(y_start);
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteCmd(0x24);
}
send display data
for(col=0; col<max_col; col++) // send 122x250bits ram 2D13
{
for(row=0; row<max_row; row++)
{
AMEPD_SSD1680_WriteData(Image_demo[pcnt]);
pcnt++;
}
}
update display data
// 在发送显示数据之后调用
AMEPD_SSD1680_WriteCmd(0x22);
AMEPD_SSD1680_WriteData(0xF7);
AMEPD_SSD1680_WriteCmd(0x20);
X/Y axis mirror display
You can set the start and end addresses of the RAMX and Y axes to make the display effect mirror X, mirror Y, or mirror X and Y together.
normal refresh
AMEPD_SSD1680_WriteCmd(0x44);
AMEPD_SSD1680_WriteData(0); // x start
AMEPD_SSD1680_WriteData(15); // x end
AMEPD_SSD1680_WriteCmd(0x45);
AMEPD_SSD1680_WriteData(0); // y start
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteData(249); // y end
AMEPD_SSD1680_WriteData(0x00);
X-axis mirror display
AMEPD_SSD1680_WriteCmd(0x44);
AMEPD_SSD1680_WriteData(16); // x start
AMEPD_SSD1680_WriteData(10); // x end
AMEPD_SSD1680_WriteCmd(0x45);
AMEPD_SSD1680_WriteData(0); // y start
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteData(249); // y end
AMEPD_SSD1680_WriteData(0x00);
Y-axis mirror display
AMEPD_SSD1680_WriteCmd(0x44);
AMEPD_SSD1680_WriteData(0); // x start
AMEPD_SSD1680_WriteData(15); // x end
AMEPD_SSD1680_WriteCmd(0x45);
AMEPD_SSD1680_WriteData(249); // y start
AMEPD_SSD1680_WriteData(0x00);
AMEPD_SSD1680_WriteData(0); // y end
AMEPD_SSD1680_WriteData(0x00);
XY axis mirroring is the same