FPGA eink controller

ice40 FPGA based custom board to control eink display

Similar projects worth following
I started this project two years ago but lost interest last year after being stuck with the custom board. I since got it working, and will share my findings.

The idea is to control an old broken kindle 3 eink display with a FPGA. I started looking at and since eink constructor is so secretive that you can't find any information. I got some success with a stm32f4 microcontroller but was disapointed by the poor performance (low refresh, black and white only). So I decided to do something better using an FPGA and some memory, I started with the ice40 Olimex board

Essential scrap website provide information about power driving of theses screen, but I was more interested in the signal driving, so I choose to use the TI TPS65185 IC which manage everything (special thanks to @Arthur Admiraal for his design which I partially reused).

I used ICE40 because of the open-source toolchain available

The memory allow to include a framebuffer, my Verilog implement a small SPI interface to communicate with the controller.

To simplify the development, I finally created my own little tool

The board is specificaly made for Kindle 3 display (ED060SC7), but should works with some other display from this generation (ED060SCE found in Kobo) which are 6" 800x600 16 colors.

Hardest part was to implement "waveform" which allow to make smooth and fast transition between screen refresh.

  • 1 × TPS65185 Power management IC
  • 1 × ICE40HX1K Logic ICs / Programmable Logic: FPGAs
  • 1 × K6R4016V1DND SRAM

  • Details about the waveform implementation

    Julien01/13/2019 at 12:48 0 comments

    Since multiple people ask me more details about the waveform format used with the FPGA, here is some information.

    Each line is one of the phase containing an array of the 4x4 transition possible in the form of 16x2 32bit value (0xFFFFFFFF):
    [white to white, white to light grey, white to dark grey, white to black,
    light grey to white, light grey to light grey, light grey to dark grey, light grey to black,
    dark grey to white, dark grey to light grey, dark grey to dark grey, dark grey to black,
    black to white, black to light grey, black to dark grey, black to black]

    Each entry take 2bits (0,1,2,3 3 never being used).

    For example, if you take line 5 of
    0x4028a098 = 0b01000000001010001010000010011000

    So to go from white to white, we will need to apply -V:

    To go from black to white, we will need to apply +V:
    You can see the algorithm there
    waveform_phase[prev_pixel1 + pixel1 + 1],waveform_phase[prev_pixel1 + pixel1]

    If previous pixel is black and pixel is white, we would have array[3<<3+0+1:3<<3+0] = array[25:24] (

  • Waveforms binary extract

    Julien04/21/2017 at 06:11 0 comments

    In the Kindle 3 screen, the waveform is actually integrated into an SPI flash in the ribbon cable. In others e-reader, this can generaly be found in the firmware. E-Ink (PVI) created his own format, supported by custom controller, and some dedicated Epson chip. I think these controllers are obsoleted since CPU manufacturers does integrate the controller directly. Actually the main (only?) manufacturer which provide CPU supporting eink screen is Freescale (imx6 solo) and they created their format as well.

    I did not integrate the SPI signal out of the ribbon, but somebody already dumped the data, so I used that for working on an "extractor" to convert this data for the FPGA. As the whole technology, there is very few information about this PVI format. You can find some information in linux kernel (about the header of the binary), the rest is mostly guess : I'm not completely sure of the dumper yet, but the data extrated does give some correct results.


  • Ebook reader test video

    Julien04/15/2017 at 17:14 0 comments

    Test with a homemade WIP epub reader, using ifusb interface ~ 1 fps

  • Waveforms table introduction

    Julien04/14/2017 at 16:14 1 comment

    With eink display, you cannot just send "set pixel black", "set pixel white" or "set pixel grey", the brightness of display depend on a sequence of voltage applied for a certain time on pixel.

    The table found in "Source driver" section on Essential Scrap site is incomplete, when you send 0b10, you do not actually set pixel white, you apply a voltage to set the pixel lighter, and 0b01 to set the pixel darker. It is why in his implementation, Petteri must apply multiple times the value to obtain the wanted color and apply the voltage longer than the screen can achieve. This approch will works, but the problem is it will be pretty slow when you want to update the screen.

    To get around that and get better result, eink manufacturer introduce what they call "waveforms table". This table describes the transition you must apply to obtain the faster results to go from one color to another.

    An example if you want to go from white to black, they can say that you will achieve that in 4 clock cycle in the form of 0b10 0b01 0b01 0b01, to go from grey to darker grey, the table can be something like 0b01 0b01 0b10 0b01, etc (it is an example, in general it is about 20 or 40 cycles).

    These waveforms are very difficult to obtain, since each eink display will have his own table, and the table will depend on temperature as well ! It is why I took some times to reverse engineering E-Ink (PVI) and Freescale binary format to extract some of these table to use them in the FPGA.

    Note there is multiple tables which correspond to different usage optimization : black and white, 2-bit/4 colors, 4-bit/16 colors (more on that later).

    Finally, this technique give really fast results, but after some times, you will see some "ghosting", some pixel from previous images are lighter or darker than they should, so a complete refresh is needed (see the "Page refresh" config in your kindle : you can set how regulary your should apply this full refresh).


    Petteri Aimonen's essential scrap waveform reverse engineering:

    Petteri Aimonen's eink driver implementation :

    My utils to extract waveform from binary :

    Example 2-bit waveform for ED060SC7 :

View all 4 project logs

Enjoy this project?



teraz wrote 12/09/2021 at 19:24 point

what You think about orange crab?

is lipo and more memory

  Are you sure? yes | no

Giovanni wrote 04/18/2021 at 23:53 point

Hi, your e-ink project has renewed interest from an e-ink laptop project. You're welcome to join:

  Are you sure? yes | no

Dmitry Mamontov wrote 10/22/2019 at 07:13 point

And you can see the ifusb connection diagram to the controller somewhere. I see the resistors, what kind of denomination do they have? Sorry for such a simple question)

  Are you sure? yes | no

pascal.jakobs wrote 09/25/2018 at 10:56 point

I'd love to see this working on a raspberry pi. Am I dreaming? Does anybody know such a project?

  Are you sure? yes | no

pascal.jakobs wrote 09/25/2018 at 10:56 point

I'd love to see this working on a raspberry pi. Am I dreaming? Does anybody know such a project?

  Are you sure? yes | no

Julien wrote 01/13/2019 at 12:55 point

Hi @pascal.jakobs 

Yes, it may work with raspberry pi but a driver must be developped. I think Linux already include a I2C TPS65185 driver (power supply). But a special driver for my SPI protocol would be needed.

  Are you sure? yes | no

fabian wrote 08/12/2018 at 19:22 point

very quickly, great.

is possible to add normal terminal and show scrolling text? for example run mc linux

  Are you sure? yes | no

Julien wrote 01/13/2019 at 12:56 point

Hi @fabian 

In theory yes, but a driver must be developped.

  Are you sure? yes | no

snorlaxhk wrote 05/31/2018 at 02:02 point

I have great interest to your e-ink project, however, I can't contact you through private message here....(and i don't know why), can you contact me through email? My email is

  Are you sure? yes | no

Jean-Marc wrote 12/07/2017 at 09:11 point

Can you do partial refresh? I need a display to make a daylight-legible dashboard, and I want to display parameters that change every second. I see your refresh rate can meet this, but at the expense of an uncomfortable flicker.

  Are you sure? yes | no

Julien wrote 01/13/2019 at 12:53 point

Hi @Jean-Marc ,

Sorry, partial refresh is not supported yet. In theory, it should work with a adapted waveform

  Are you sure? yes | no

damiani83 wrote 08/01/2017 at 12:03 point

How do the data in the file be interpreted (Example 2-bit waveform for ED060SC7 waveform_gc4.hex)??

  Are you sure? yes | no

Julien wrote 08/07/2017 at 18:23 point

Hi @damiani83 

Each line is a phase of the waveform, which is a an array of the 4x4 transitions possible (white to light grey, light grey to dark grey, etc) and the 2bits values are the actual signaling to pass to the panel (0b00 0b01 and 0b10)

You can find more details in the source code

  Are you sure? yes | no

damiani83 wrote 12/04/2018 at 14:23 point

for each phase, how and what data to take in the 4x4 array? 

wire [7:0] data_out;

assign data_out = {
waveform_phase[prev_pixel4 + pixel4 + 1],waveform_phase[prev_pixel4 + pixel4],
waveform_phase[prev_pixel3 + pixel3 + 1],waveform_phase[prev_pixel3 + pixel3],
waveform_phase[prev_pixel2 + pixel2 + 1],waveform_phase[prev_pixel2 + pixel2],
waveform_phase[prev_pixel1 + pixel1 + 1],waveform_phase[prev_pixel1 + pixel1]

you can explain this code with an example??

  Are you sure? yes | no

Jasmine Brackett wrote 05/09/2017 at 16:25 point

Great project! I just thought I'd let you know that it was mentioned on the Tindie Blog today -

  Are you sure? yes | no

Julien wrote 05/09/2017 at 17:43 point

Nice, thank you !

  Are you sure? yes | no

shemaraphael wrote 04/27/2017 at 03:13 point

I want to use this to make an e-ink laptop. I'm having trouble finding the SRAM, perhaps I'm not looking in the right place. Is it still available on Digi-Key? If not, is there something else that would work?

  Are you sure? yes | no

Roeland Kindt wrote 05/03/2017 at 12:36 point

have a look at psram to make your life easier.

  Are you sure? yes | no

Trevor Johansen Aase wrote 04/22/2017 at 05:13 point

What was the cost of parts on the PCB? I see the displays are only $25 on eBay so could be an inexpensive project to play with.

  Are you sure? yes | no

Julien wrote 04/22/2017 at 06:22 point

PCB itself cost $30 on OSHPark (x3). In quantity 1 on digikey : PMIC cost ~$4.5, FPGA ~$5, SRAM between $3 and $4, 100Mhz crystal $2, LDOs $2, Screen conn $2, Ext conn. $2, SPI flash $1, so with the passives count around ~$25 in components.

  Are you sure? yes | no

Trevor Johansen Aase wrote 04/22/2017 at 16:09 point

Thanks! Not much at all. I may think about a new weather station/thermostat unit in future projects.

  Are you sure? yes | no

oshpark wrote 04/20/2017 at 18:28 point

Nice to see this project on Hackaday blog :)

  Are you sure? yes | no

Julien wrote 04/20/2017 at 14:31 point

@repkid Yes, theoricaly these panel are very similar. I think power part will works unmodified. On the other side connector won't fit, so some modification of the schematics & layout are needed. Maybe verilog need to be modified as well, if I remember some signals are active low instead of active high or the opposite.

  Are you sure? yes | no

repkid wrote 04/21/2017 at 10:25 point

Thanks for the reply, I will try to get it to work with the ED060SC4. Are you going to release more waveforms?

  Are you sure? yes | no

Julien wrote 04/22/2017 at 06:06 point

You can generate the waveform with the utils I provide, but I'm still figuring a way to find original binary waveforms. I found the ED060SC7 searching Google ...

  Are you sure? yes | no

Julien wrote 04/20/2017 at 14:26 point

  Are you sure? yes | no

repkid wrote 04/20/2017 at 12:59 point

This looks amazing, can this also be used to drive the ED060SC4?

  Are you sure? yes | no

BeagleBoard Foundation wrote 04/18/2017 at 01:56 point

Very exciting!  Check it out, @Michael Welling.  Maybe this would work with the new BeagleBone cape you are working on.

  Are you sure? yes | no

oshpark wrote 04/18/2017 at 01:41 point

Amazing project!  Thanks for sharing all the details

  Are you sure? yes | no

Julien wrote 04/14/2017 at 07:19 point

Hi @Brangor, I sourced all components from and the PCB from OSHPark, you should be able to make it at home if you have some soldering skills. You will need hot air soldering station because of TPS65185 which is in QFN package (and it is easier for small 603 components). Schematics and layout for free version of Eagle CAD are available here :

  Are you sure? yes | no

Brangor wrote 04/14/2017 at 02:41 point

Where do you go to purchase these components, and could you just soldier them on yourself, or would you use a service for that?  I see the board listed here: - how much work would it be to put the right components onto it? Would it be done by just following some of the blogs on eink controllers that you listed with essentialscrap and spritesmods?

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates