EPD
Dependencies: mbed-STM32F103C8T6 mbed
main.cpp@0:1d2c0afef43c, 2017-12-29 (annotated)
- Committer:
- spin7ion
- Date:
- Fri Dec 29 22:35:18 2017 +0000
- Revision:
- 0:1d2c0afef43c
test;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
spin7ion | 0:1d2c0afef43c | 1 | #include "stm32f103c8t6.h" |
spin7ion | 0:1d2c0afef43c | 2 | #include "mbed.h" |
spin7ion | 0:1d2c0afef43c | 3 | #include "epd.h" |
spin7ion | 0:1d2c0afef43c | 4 | |
spin7ion | 0:1d2c0afef43c | 5 | DigitalOut myled1(LED1); |
spin7ion | 0:1d2c0afef43c | 6 | |
spin7ion | 0:1d2c0afef43c | 7 | DigitalOut edp_reset(PB_0); |
spin7ion | 0:1d2c0afef43c | 8 | DigitalOut edp_dataCommand(PB_10); |
spin7ion | 0:1d2c0afef43c | 9 | DigitalOut edp_chipSelect(PA_4); |
spin7ion | 0:1d2c0afef43c | 10 | DigitalIn edp_busy(PB_11); |
spin7ion | 0:1d2c0afef43c | 11 | SPI spi(PA_7,PA_6,PA_5); // mosi, miso, sclk, ss |
spin7ion | 0:1d2c0afef43c | 12 | //DigitalOut eink(PB_0); |
spin7ion | 0:1d2c0afef43c | 13 | /* |
spin7ion | 0:1d2c0afef43c | 14 | EaEpaper epaper(NC, // PWR_CTRL |
spin7ion | 0:1d2c0afef43c | 15 | NC, // BORDER |
spin7ion | 0:1d2c0afef43c | 16 | PB_10, // DISCHARGE |
spin7ion | 0:1d2c0afef43c | 17 | PB_0, // RESET_DISP |
spin7ion | 0:1d2c0afef43c | 18 | PB_11, // BUSY |
spin7ion | 0:1d2c0afef43c | 19 | PA_4, // SSEL |
spin7ion | 0:1d2c0afef43c | 20 | NC, // PWM |
spin7ion | 0:1d2c0afef43c | 21 | PA_7,PA_6,PA_5, // MOSI,MISO,SCLK |
spin7ion | 0:1d2c0afef43c | 22 | "eink"); // SDA,SCL */ |
spin7ion | 0:1d2c0afef43c | 23 | |
spin7ion | 0:1d2c0afef43c | 24 | void EPD_SendCommand(unsigned char data) { |
spin7ion | 0:1d2c0afef43c | 25 | edp_chipSelect=0; |
spin7ion | 0:1d2c0afef43c | 26 | edp_dataCommand=0; |
spin7ion | 0:1d2c0afef43c | 27 | spi.write(data); |
spin7ion | 0:1d2c0afef43c | 28 | edp_chipSelect=1; |
spin7ion | 0:1d2c0afef43c | 29 | } |
spin7ion | 0:1d2c0afef43c | 30 | |
spin7ion | 0:1d2c0afef43c | 31 | void EPD_SendData(unsigned char data) { |
spin7ion | 0:1d2c0afef43c | 32 | edp_chipSelect=0; |
spin7ion | 0:1d2c0afef43c | 33 | edp_dataCommand=1; |
spin7ion | 0:1d2c0afef43c | 34 | spi.write(data); |
spin7ion | 0:1d2c0afef43c | 35 | edp_chipSelect=1; |
spin7ion | 0:1d2c0afef43c | 36 | } |
spin7ion | 0:1d2c0afef43c | 37 | |
spin7ion | 0:1d2c0afef43c | 38 | void EPD_Reset() { |
spin7ion | 0:1d2c0afef43c | 39 | edp_reset=0; |
spin7ion | 0:1d2c0afef43c | 40 | wait_ms(200); |
spin7ion | 0:1d2c0afef43c | 41 | edp_reset=1; |
spin7ion | 0:1d2c0afef43c | 42 | wait_ms(200); |
spin7ion | 0:1d2c0afef43c | 43 | } |
spin7ion | 0:1d2c0afef43c | 44 | |
spin7ion | 0:1d2c0afef43c | 45 | void EPD_WaitUntilIdle() { |
spin7ion | 0:1d2c0afef43c | 46 | while(edp_busy == 1) { //0: busy, 1: idle |
spin7ion | 0:1d2c0afef43c | 47 | wait_ms(100); |
spin7ion | 0:1d2c0afef43c | 48 | } |
spin7ion | 0:1d2c0afef43c | 49 | } |
spin7ion | 0:1d2c0afef43c | 50 | |
spin7ion | 0:1d2c0afef43c | 51 | /** |
spin7ion | 0:1d2c0afef43c | 52 | * @brief: private function to specify the memory area for data R/W |
spin7ion | 0:1d2c0afef43c | 53 | */ |
spin7ion | 0:1d2c0afef43c | 54 | static void EPD_SetMemoryArea(int x_start, int y_start, int x_end, int y_end) { |
spin7ion | 0:1d2c0afef43c | 55 | EPD_SendCommand(SET_RAM_X_ADDRESS_START_END_POSITION); |
spin7ion | 0:1d2c0afef43c | 56 | /* x point must be the multiple of 8 or the last 3 bits will be ignored */ |
spin7ion | 0:1d2c0afef43c | 57 | EPD_SendData((x_start >> 3) & 0xFF); |
spin7ion | 0:1d2c0afef43c | 58 | EPD_SendData((x_end >> 3) & 0xFF); |
spin7ion | 0:1d2c0afef43c | 59 | EPD_SendCommand(SET_RAM_Y_ADDRESS_START_END_POSITION); |
spin7ion | 0:1d2c0afef43c | 60 | EPD_SendData(y_start & 0xFF); |
spin7ion | 0:1d2c0afef43c | 61 | EPD_SendData((y_start >> 8) & 0xFF); |
spin7ion | 0:1d2c0afef43c | 62 | EPD_SendData(y_end & 0xFF); |
spin7ion | 0:1d2c0afef43c | 63 | EPD_SendData((y_end >> 8) & 0xFF); |
spin7ion | 0:1d2c0afef43c | 64 | } |
spin7ion | 0:1d2c0afef43c | 65 | |
spin7ion | 0:1d2c0afef43c | 66 | /** |
spin7ion | 0:1d2c0afef43c | 67 | * @brief: private function to specify the start point for data R/W |
spin7ion | 0:1d2c0afef43c | 68 | */ |
spin7ion | 0:1d2c0afef43c | 69 | static void EPD_SetMemoryPointer(int x, int y) { |
spin7ion | 0:1d2c0afef43c | 70 | EPD_SendCommand(SET_RAM_X_ADDRESS_COUNTER); |
spin7ion | 0:1d2c0afef43c | 71 | /* x point must be the multiple of 8 or the last 3 bits will be ignored */ |
spin7ion | 0:1d2c0afef43c | 72 | EPD_SendData((x >> 3) & 0xFF); |
spin7ion | 0:1d2c0afef43c | 73 | EPD_SendCommand(SET_RAM_Y_ADDRESS_COUNTER); |
spin7ion | 0:1d2c0afef43c | 74 | EPD_SendData(y & 0xFF); |
spin7ion | 0:1d2c0afef43c | 75 | EPD_SendData((y >> 8) & 0xFF); |
spin7ion | 0:1d2c0afef43c | 76 | EPD_WaitUntilIdle(); |
spin7ion | 0:1d2c0afef43c | 77 | } |
spin7ion | 0:1d2c0afef43c | 78 | |
spin7ion | 0:1d2c0afef43c | 79 | void EPD_SetLut(const unsigned char* lut) { |
spin7ion | 0:1d2c0afef43c | 80 | EPD_SendCommand(WRITE_LUT_REGISTER); |
spin7ion | 0:1d2c0afef43c | 81 | /* the length of look-up table is 30 bytes */ |
spin7ion | 0:1d2c0afef43c | 82 | for (int i = 0; i < 30; i++) { |
spin7ion | 0:1d2c0afef43c | 83 | EPD_SendData(lut[i]); |
spin7ion | 0:1d2c0afef43c | 84 | } |
spin7ion | 0:1d2c0afef43c | 85 | } |
spin7ion | 0:1d2c0afef43c | 86 | |
spin7ion | 0:1d2c0afef43c | 87 | int EPD_Init() { |
spin7ion | 0:1d2c0afef43c | 88 | EPD_Reset(); |
spin7ion | 0:1d2c0afef43c | 89 | EPD_SendCommand(DRIVER_OUTPUT_CONTROL); |
spin7ion | 0:1d2c0afef43c | 90 | EPD_SendData((EPD_HEIGHT - 1) & 0xFF); |
spin7ion | 0:1d2c0afef43c | 91 | EPD_SendData(((EPD_HEIGHT - 1) >> 8) & 0xFF); |
spin7ion | 0:1d2c0afef43c | 92 | EPD_SendData(0x00); // GD = 0; SM = 0; TB = 0; |
spin7ion | 0:1d2c0afef43c | 93 | EPD_SendCommand(BOOSTER_SOFT_START_CONTROL); |
spin7ion | 0:1d2c0afef43c | 94 | EPD_SendData(0xD7); |
spin7ion | 0:1d2c0afef43c | 95 | EPD_SendData(0xD6); |
spin7ion | 0:1d2c0afef43c | 96 | EPD_SendData(0x9D); |
spin7ion | 0:1d2c0afef43c | 97 | EPD_SendCommand(WRITE_VCOM_REGISTER); |
spin7ion | 0:1d2c0afef43c | 98 | EPD_SendData(0xA8); // VCOM 7C |
spin7ion | 0:1d2c0afef43c | 99 | EPD_SendCommand(SET_DUMMY_LINE_PERIOD); |
spin7ion | 0:1d2c0afef43c | 100 | EPD_SendData(0x1A); // 4 dummy lines per gate |
spin7ion | 0:1d2c0afef43c | 101 | EPD_SendCommand(SET_GATE_TIME); |
spin7ion | 0:1d2c0afef43c | 102 | EPD_SendData(0x08); // 2us per line |
spin7ion | 0:1d2c0afef43c | 103 | EPD_SendCommand(DATA_ENTRY_MODE_SETTING); |
spin7ion | 0:1d2c0afef43c | 104 | EPD_SendData(0x03); // X increment; Y increment |
spin7ion | 0:1d2c0afef43c | 105 | EPD_SetLut(lut_full_update); |
spin7ion | 0:1d2c0afef43c | 106 | //EPD_SetLut(lut_partial_update); |
spin7ion | 0:1d2c0afef43c | 107 | /* EPD hardware init end */ |
spin7ion | 0:1d2c0afef43c | 108 | return 0; |
spin7ion | 0:1d2c0afef43c | 109 | } |
spin7ion | 0:1d2c0afef43c | 110 | |
spin7ion | 0:1d2c0afef43c | 111 | /** |
spin7ion | 0:1d2c0afef43c | 112 | * @brief: put an image buffer to the frame memory. |
spin7ion | 0:1d2c0afef43c | 113 | * this won't update the display. |
spin7ion | 0:1d2c0afef43c | 114 | */ |
spin7ion | 0:1d2c0afef43c | 115 | void EPD_SetFrameMemory( |
spin7ion | 0:1d2c0afef43c | 116 | const unsigned char* image_buffer, |
spin7ion | 0:1d2c0afef43c | 117 | int x, |
spin7ion | 0:1d2c0afef43c | 118 | int y, |
spin7ion | 0:1d2c0afef43c | 119 | int image_width, |
spin7ion | 0:1d2c0afef43c | 120 | int image_height |
spin7ion | 0:1d2c0afef43c | 121 | ) { |
spin7ion | 0:1d2c0afef43c | 122 | int x_end; |
spin7ion | 0:1d2c0afef43c | 123 | int y_end; |
spin7ion | 0:1d2c0afef43c | 124 | |
spin7ion | 0:1d2c0afef43c | 125 | if ( |
spin7ion | 0:1d2c0afef43c | 126 | image_buffer == NULL || |
spin7ion | 0:1d2c0afef43c | 127 | x < 0 || image_width < 0 || |
spin7ion | 0:1d2c0afef43c | 128 | y < 0 || image_height < 0 |
spin7ion | 0:1d2c0afef43c | 129 | ) { |
spin7ion | 0:1d2c0afef43c | 130 | return; |
spin7ion | 0:1d2c0afef43c | 131 | } |
spin7ion | 0:1d2c0afef43c | 132 | /* x point must be the multiple of 8 or the last 3 bits will be ignored */ |
spin7ion | 0:1d2c0afef43c | 133 | x &= 0xF8; |
spin7ion | 0:1d2c0afef43c | 134 | image_width &= 0xF8; |
spin7ion | 0:1d2c0afef43c | 135 | if (x + image_width >= EPD_WIDTH) { |
spin7ion | 0:1d2c0afef43c | 136 | x_end = EPD_WIDTH - 1; |
spin7ion | 0:1d2c0afef43c | 137 | } else { |
spin7ion | 0:1d2c0afef43c | 138 | x_end = x + image_width - 1; |
spin7ion | 0:1d2c0afef43c | 139 | } |
spin7ion | 0:1d2c0afef43c | 140 | if (y + image_height >= EPD_HEIGHT) { |
spin7ion | 0:1d2c0afef43c | 141 | y_end = EPD_HEIGHT - 1; |
spin7ion | 0:1d2c0afef43c | 142 | } else { |
spin7ion | 0:1d2c0afef43c | 143 | y_end = y + image_height - 1; |
spin7ion | 0:1d2c0afef43c | 144 | } |
spin7ion | 0:1d2c0afef43c | 145 | EPD_SetMemoryArea(x, y, x_end, y_end); |
spin7ion | 0:1d2c0afef43c | 146 | EPD_SetMemoryPointer(x, y); |
spin7ion | 0:1d2c0afef43c | 147 | EPD_SendCommand(WRITE_RAM); |
spin7ion | 0:1d2c0afef43c | 148 | /* send the image data */ |
spin7ion | 0:1d2c0afef43c | 149 | for (int j = 0; j < y_end - y + 1; j++) { |
spin7ion | 0:1d2c0afef43c | 150 | for (int i = 0; i < (x_end - x + 1) / 8; i++) { |
spin7ion | 0:1d2c0afef43c | 151 | EPD_SendData(image_buffer[i + j * (image_width / 8)]); |
spin7ion | 0:1d2c0afef43c | 152 | } |
spin7ion | 0:1d2c0afef43c | 153 | } |
spin7ion | 0:1d2c0afef43c | 154 | } |
spin7ion | 0:1d2c0afef43c | 155 | |
spin7ion | 0:1d2c0afef43c | 156 | /** |
spin7ion | 0:1d2c0afef43c | 157 | * @brief: clear the frame memory with the specified color. |
spin7ion | 0:1d2c0afef43c | 158 | * this won't update the display. |
spin7ion | 0:1d2c0afef43c | 159 | */ |
spin7ion | 0:1d2c0afef43c | 160 | void EPD_ClearFrameMemory(unsigned char color) { |
spin7ion | 0:1d2c0afef43c | 161 | EPD_SetMemoryArea(0, 0, EPD_WIDTH - 1, EPD_HEIGHT - 1); |
spin7ion | 0:1d2c0afef43c | 162 | EPD_SetMemoryPointer(0, 0); |
spin7ion | 0:1d2c0afef43c | 163 | EPD_SendCommand(WRITE_RAM); |
spin7ion | 0:1d2c0afef43c | 164 | /* send the color data */ |
spin7ion | 0:1d2c0afef43c | 165 | for (int i = 0; i < EPD_WIDTH / 8 * EPD_HEIGHT; i++) { |
spin7ion | 0:1d2c0afef43c | 166 | EPD_SendData(color); |
spin7ion | 0:1d2c0afef43c | 167 | } |
spin7ion | 0:1d2c0afef43c | 168 | } |
spin7ion | 0:1d2c0afef43c | 169 | |
spin7ion | 0:1d2c0afef43c | 170 | /** |
spin7ion | 0:1d2c0afef43c | 171 | * @brief: update the display |
spin7ion | 0:1d2c0afef43c | 172 | * there are 2 memory areas embedded in the e-paper display |
spin7ion | 0:1d2c0afef43c | 173 | * but once this function is called, |
spin7ion | 0:1d2c0afef43c | 174 | * the the next action of SetFrameMemory or ClearFrame will |
spin7ion | 0:1d2c0afef43c | 175 | * set the other memory area. |
spin7ion | 0:1d2c0afef43c | 176 | */ |
spin7ion | 0:1d2c0afef43c | 177 | void EPD_DisplayFrame() { |
spin7ion | 0:1d2c0afef43c | 178 | EPD_SendCommand(DISPLAY_UPDATE_CONTROL_2); |
spin7ion | 0:1d2c0afef43c | 179 | EPD_SendData(0xC4); |
spin7ion | 0:1d2c0afef43c | 180 | EPD_SendCommand(MASTER_ACTIVATION); |
spin7ion | 0:1d2c0afef43c | 181 | EPD_SendCommand(TERMINATE_FRAME_READ_WRITE); |
spin7ion | 0:1d2c0afef43c | 182 | EPD_WaitUntilIdle(); |
spin7ion | 0:1d2c0afef43c | 183 | } |
spin7ion | 0:1d2c0afef43c | 184 | |
spin7ion | 0:1d2c0afef43c | 185 | /** |
spin7ion | 0:1d2c0afef43c | 186 | * @brief: After this command is transmitted, the chip would enter the |
spin7ion | 0:1d2c0afef43c | 187 | * deep-sleep mode to save power. |
spin7ion | 0:1d2c0afef43c | 188 | * The deep sleep mode would return to standby by hardware reset. |
spin7ion | 0:1d2c0afef43c | 189 | * You can use EPD_Init() to awaken |
spin7ion | 0:1d2c0afef43c | 190 | */ |
spin7ion | 0:1d2c0afef43c | 191 | void EPD_Sleep() { |
spin7ion | 0:1d2c0afef43c | 192 | EPD_SendCommand(DEEP_SLEEP_MODE); |
spin7ion | 0:1d2c0afef43c | 193 | EPD_WaitUntilIdle(); |
spin7ion | 0:1d2c0afef43c | 194 | } |
spin7ion | 0:1d2c0afef43c | 195 | |
spin7ion | 0:1d2c0afef43c | 196 | void setChar(char chr, int x, int y, unsigned char color){ |
spin7ion | 0:1d2c0afef43c | 197 | unsigned char arr[8]; |
spin7ion | 0:1d2c0afef43c | 198 | memcpy(arr, (unsigned char*)&(FONT8x8[chr - 0x1F][0]), 8); |
spin7ion | 0:1d2c0afef43c | 199 | |
spin7ion | 0:1d2c0afef43c | 200 | if(color==0){ |
spin7ion | 0:1d2c0afef43c | 201 | for(int i=0;i<8;i++){ |
spin7ion | 0:1d2c0afef43c | 202 | arr[i]=~arr[i]; |
spin7ion | 0:1d2c0afef43c | 203 | } |
spin7ion | 0:1d2c0afef43c | 204 | } |
spin7ion | 0:1d2c0afef43c | 205 | |
spin7ion | 0:1d2c0afef43c | 206 | EPD_SetFrameMemory(arr,x,y,8,8); |
spin7ion | 0:1d2c0afef43c | 207 | } |
spin7ion | 0:1d2c0afef43c | 208 | |
spin7ion | 0:1d2c0afef43c | 209 | void setString(char *str, int len, int x, int y, unsigned char color){ |
spin7ion | 0:1d2c0afef43c | 210 | for (int i=0;i<len;i++) { |
spin7ion | 0:1d2c0afef43c | 211 | if(str[i]=='\n' && i<len-1){y+=8;i++;x-=i*8;} |
spin7ion | 0:1d2c0afef43c | 212 | setChar(str[i], x+i*8, y, color); |
spin7ion | 0:1d2c0afef43c | 213 | } |
spin7ion | 0:1d2c0afef43c | 214 | } |
spin7ion | 0:1d2c0afef43c | 215 | |
spin7ion | 0:1d2c0afef43c | 216 | int main() { |
spin7ion | 0:1d2c0afef43c | 217 | confSysClock(); |
spin7ion | 0:1d2c0afef43c | 218 | spi.format(8,0); |
spin7ion | 0:1d2c0afef43c | 219 | spi.frequency(4000000); |
spin7ion | 0:1d2c0afef43c | 220 | |
spin7ion | 0:1d2c0afef43c | 221 | EPD_Init(); |
spin7ion | 0:1d2c0afef43c | 222 | |
spin7ion | 0:1d2c0afef43c | 223 | //EPD_ClearFrameMemory(BACKGROUND_WHITE); |
spin7ion | 0:1d2c0afef43c | 224 | //EPD_DisplayFrame(); |
spin7ion | 0:1d2c0afef43c | 225 | setString("Alexander\nSemion",16,0,0,0); |
spin7ion | 0:1d2c0afef43c | 226 | EPD_DisplayFrame(); |
spin7ion | 0:1d2c0afef43c | 227 | /*unsigned char arr[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
spin7ion | 0:1d2c0afef43c | 228 | EPD_SetFrameMemory((unsigned char*)&(FONT8x8['S' - 0x1F][0]),0,0,8,8); |
spin7ion | 0:1d2c0afef43c | 229 | EPD_SetFrameMemory((unsigned char*)&(FONT8x8['P' - 0x1F][0]),8,0,8,8); |
spin7ion | 0:1d2c0afef43c | 230 | EPD_SetFrameMemory((unsigned char*)&(FONT8x8['I' - 0x1F][0]),16,0,8,8); |
spin7ion | 0:1d2c0afef43c | 231 | EPD_SetFrameMemory((unsigned char*)&(FONT8x8['N' - 0x1F][0]),24,0,8,8); |
spin7ion | 0:1d2c0afef43c | 232 | EPD_SetFrameMemory((unsigned char*)&(FONT8x8['7' - 0x1F][0]),32,0,8,8); |
spin7ion | 0:1d2c0afef43c | 233 | EPD_SetFrameMemory((unsigned char*)&(FONT8x8['I' - 0x1F][0]),40,0,8,8); |
spin7ion | 0:1d2c0afef43c | 234 | EPD_SetFrameMemory((unsigned char*)&(FONT8x8['O' - 0x1F][0]),48,0,8,8); |
spin7ion | 0:1d2c0afef43c | 235 | EPD_SetFrameMemory((unsigned char*)&(FONT8x8['N' - 0x1F][0]),56,0,8,8); |
spin7ion | 0:1d2c0afef43c | 236 | EPD_DisplayFrame();*/ |
spin7ion | 0:1d2c0afef43c | 237 | /* |
spin7ion | 0:1d2c0afef43c | 238 | while(1){ |
spin7ion | 0:1d2c0afef43c | 239 | myled1 = 1; |
spin7ion | 0:1d2c0afef43c | 240 | wait_ms(1000); |
spin7ion | 0:1d2c0afef43c | 241 | myled1 = 0; |
spin7ion | 0:1d2c0afef43c | 242 | wait_ms(1000); |
spin7ion | 0:1d2c0afef43c | 243 | }*/ |
spin7ion | 0:1d2c0afef43c | 244 | } |