# HG changeset patch # User Paul Boddie # Date 1365359752 0 # Node ID f6507ae3df9322c00db388b1b050cfccca608154 Imported the Pervasive Displays code from the Raspberry Pi archive demonstrating the Embedded Artists EM027AS012 E-Paper Display Adapter Board, along with a modified version of the Makefile used in the ben-arduino-usb project. diff -r 000000000000 -r f6507ae3df93 Display_COG_Process.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Display_COG_Process.c Sun Apr 07 18:35:52 2013 +0000 @@ -0,0 +1,650 @@ +// Copyright 2013 Pervasive Displays, Inc. +// +// 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. + +/****************************************************************************** + * Includes + *****************************************************************************/ +//#include "driver_config.h" +//#include "target_config.h" +//#include "type.h" +//#include "gpio.h" +#include "Display_COG_Process.h" +#include "Display_Hardware_Driver.h" +#include "Display_Controller.h" + + +/****************************************************************************** + * Defines and typedefs + *****************************************************************************/ +#define _GaugeFrameTimeMark 0 + +const COG_Parameters_t COG_Parameters[3]= { + { //for 1.44" + {0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0x00}, + 0x03, + (128/8), + 96, + (((128+96)*2)/8), + (43), + 480 + }, + { //for 2.0" + {0x00,0x00,0x00,0x00,0x01,0xFF,0xE0,0x00}, + 0x03, + (200/8), + 96, + (((200+96)*2)/8)+1, + (53), + 480 + }, + { //for 2.7" + {0x00,0x00,0x00,0x7F,0xFF,0xFE,0x00,0x00}, + 0x00, + (264/8), + 176, + (((264+176)*2)/8)+1, + 105, + 630 + }, +}; + +const uint8_t ScanTable[4] = {0xC0, 0x30, 0x0C, 0x03}; + + +/****************************************************************************** + * Local variables + *****************************************************************************/ +static uint32_t StageTime = 480; +static COG_LineDataPacket_t COG_Line; +static uint16_t EPD_Type_Index = 0; +static uint16_t cnt = 0; +static uint32_t Currentframe; +static uint8_t *DataLineEven; +static uint8_t *DataLineOdd; +static uint8_t *DataLineScan; +static uint8_t *DisplayOrgPtr; + + +/****************************************************************************** + * Local functions + *****************************************************************************/ +static void SetTemperature_Factor(uint8_t EPD_Type_Index) +{ + int16_t Temperature; + + //Get current temperature + Temperature = epd_get_temperature(); + + if (Temperature < -10) + { + StageTime = COG_Parameters[EPD_Type_Index].StageTime * 17; + } + else if (Temperature < -5) + { + StageTime = COG_Parameters[EPD_Type_Index].StageTime * 12; + } + else if (Temperature < 5) + { + StageTime = COG_Parameters[EPD_Type_Index].StageTime * 8; + } + else if (Temperature < 10) + { + StageTime = COG_Parameters[EPD_Type_Index].StageTime * 4; + } + else if (Temperature < 15) + { + StageTime = COG_Parameters[EPD_Type_Index].StageTime * 3; + } + else if (Temperature < 20) + { + StageTime = COG_Parameters[EPD_Type_Index].StageTime * 2; + } + else if (Temperature < 40) + { + StageTime = COG_Parameters[EPD_Type_Index].StageTime * 1; + } + else + { + StageTime = (COG_Parameters[EPD_Type_Index].StageTime * 7)/10; + } +} + +static void Driver_TypeSelect(uint8_t typeIndex) +{ + switch(typeIndex) + { + case EPDType_144: + DataLineEven=&COG_Line.LineDatas.COG_144LineData.Even[0]; + DataLineOdd=&COG_Line.LineDatas.COG_144LineData.Odd[0]; + DataLineScan=&COG_Line.LineDatas.COG_144LineData.Scan[0]; + break; + case EPDType_200: + DataLineEven=&COG_Line.LineDatas.COG_20LineData.Even[0]; + DataLineOdd=&COG_Line.LineDatas.COG_20LineData.Odd[0]; + DataLineScan=&COG_Line.LineDatas.COG_20LineData.Scan[0]; + break; + case EPDType_270: + DataLineEven=&COG_Line.LineDatas.COG_27LineData.Even[0]; + DataLineOdd=&COG_Line.LineDatas.COG_27LineData.Odd[0]; + DataLineScan=&COG_Line.LineDatas.COG_27LineData.Scan[0]; + break; + } +} + +//#pragma GCC optimize ("-O3") +static void Display_Stage_1 (uint8_t *PreviousPicture) +{ + uint16_t i,j,k; // general counters + uint8_t TempByte; // Temporary storage for image data check + uint16_t StartClock; +#ifdef DISPLAY_180_DEGREE + uint8_t *DataLinePrt; + DisplayOrgPtr = (PreviousPicture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); +#else + DisplayOrgPtr = PreviousPicture; +#endif + Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; +//TestPinTrigger(); + cnt = 0; + StartClock = epd_GetCurrentTimeTick(); + do + { +// TestPin2Trigger(); + PreviousPicture = DisplayOrgPtr; +#ifdef DISPLAY_180_DEGREE + DataLinePrt = PreviousPicture; +#endif + for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line + { + // SPI (0x04, ...) + epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); + k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; + for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // check every bit in the line + { + TempByte = (*PreviousPicture++); +#ifdef DISPLAY_180_DEGREE + DataLineEven[j] = ((TempByte & 0x80) ? BLACK3 : WHITE3) + | ((TempByte & 0x20) ? BLACK2 : WHITE2) + | ((TempByte & 0x08) ? BLACK1 : WHITE1) + | ((TempByte & 0x02) ? BLACK0 : WHITE0); + + DataLineOdd[k--] = ((TempByte & 0x01) ? BLACK3 : WHITE3) + | ((TempByte & 0x04) ? BLACK2 : WHITE2) + | ((TempByte & 0x10) ? BLACK1 : WHITE1) + | ((TempByte & 0x40) ? BLACK0 : WHITE0); + DataLinePrt--; +#else + DataLineOdd[j] = ((TempByte & 0x80) ? BLACK3 : WHITE3) + | ((TempByte & 0x20) ? BLACK2 : WHITE2) + | ((TempByte & 0x08) ? BLACK1 : WHITE1) + | ((TempByte & 0x02) ? BLACK0 : WHITE0); + + DataLineEven[k--] = ((TempByte & 0x01) ? BLACK3 : WHITE3) + | ((TempByte & 0x04) ? BLACK2 : WHITE2) + | ((TempByte & 0x10) ? BLACK1 : WHITE1) + | ((TempByte & 0x40) ? BLACK0 : WHITE0); +#endif + } +#ifdef DISPLAY_180_DEGREE + PreviousPicture = DataLinePrt; +#endif + DataLineScan[(i>>2)] = ScanTable[(i%4)]; + // SPI (0x0a, line data....) + epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); + + // SPI (0x02, 0x25) + epd_SPI_Send_Byte(0x02, 0x2F); + + DataLineScan[(i>>2)] = 0; + } +#if(!_GaugeFrameTimeMark) + if(COG_Parameters[EPD_Type_Index].FrameTime>0) + { + while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); + } +#endif + //TestPin2Trigger(); + Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; + cnt++; + }while (StageTime>Currentframe); +// TestPin2Trigger(); + while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); +// TestPin2Trigger(); +// TestPinTrigger(); +} + +//#pragma GCC optimize ("-O3") +static void Display_Stage_2 (uint8_t *PreviousPicture) +{ + uint16_t i, j, k; // general counters + uint8_t TempByte; // Temporary storage for image data check + uint16_t StartClock; +#ifdef DISPLAY_180_DEGREE + uint8_t *DataLinePrt; + DisplayOrgPtr = (PreviousPicture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); +#else + DisplayOrgPtr = PreviousPicture; +#endif + +// TestPinTrigger(); + cnt = 0; + Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; + StartClock = epd_GetCurrentTimeTick(); + do + { +// TestPin2Trigger(); + PreviousPicture = DisplayOrgPtr; +#ifdef DISPLAY_180_DEGREE + DataLinePrt = PreviousPicture; +#endif + for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line + { + // SPI (0x04, ...) + epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); + k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; + for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // make every bit in the line black + { + TempByte =(*PreviousPicture++); +#ifdef DISPLAY_180_DEGREE + DataLineEven[j] = ((TempByte & 0x80) ? WHITE3 : NOTHING) + | ((TempByte & 0x20) ? WHITE2 : NOTHING) + | ((TempByte & 0x08) ? WHITE1 : NOTHING) + | ((TempByte & 0x02) ? WHITE0 : NOTHING); + DataLineOdd[k--] = ((TempByte & 0x01) ? WHITE3 : NOTHING) + | ((TempByte & 0x04) ? WHITE2 : NOTHING) + | ((TempByte & 0x10) ? WHITE1 : NOTHING) + | ((TempByte & 0x40) ? WHITE0 : NOTHING); + DataLinePrt--; +#else + DataLineOdd[j] = ((TempByte & 0x80) ? WHITE3 : NOTHING) + | ((TempByte & 0x20) ? WHITE2 : NOTHING) + | ((TempByte & 0x08) ? WHITE1 : NOTHING) + | ((TempByte & 0x02) ? WHITE0 : NOTHING); + DataLineEven[k--] = ((TempByte & 0x01) ? WHITE3 : NOTHING) + | ((TempByte & 0x04) ? WHITE2 : NOTHING) + | ((TempByte & 0x10) ? WHITE1 : NOTHING) + | ((TempByte & 0x40) ? WHITE0 : NOTHING); +#endif + } + +#ifdef DISPLAY_180_DEGREE + PreviousPicture = DataLinePrt; +#endif + DataLineScan[(i>>2)] = ScanTable[(i%4)]; + // SPI (0x0a, line data....) + epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); + + epd_SPI_Send_Byte(0x02, 0x25); + + DataLineScan[(i>>2)] = 0; + } +#if(!_GaugeFrameTimeMark) + if(COG_Parameters[EPD_Type_Index].FrameTime>0) + { + while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); + } +#endif + //TestPin2Trigger(); + Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; + cnt++; + }while (StageTime>Currentframe); +// TestPin2Trigger(); + while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); +// TestPin2Trigger(); +// TestPinTrigger(); +} + + +//#pragma GCC optimize ("-O3") +static void Display_Stage_3 (uint8_t *Picture) +{ + uint16_t i, j,k; // general counters + uint8_t TempByte; // Temporary storage for image data check + uint16_t StartClock; +#ifdef DISPLAY_180_DEGREE + uint8_t *DataLinePrt; + DisplayOrgPtr = (Picture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); +#else + DisplayOrgPtr = Picture; +#endif + Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; + cnt = 0; +// TestPinTrigger(); + StartClock = epd_GetCurrentTimeTick(); + do + { +// TestPin2Trigger(); + Picture = DisplayOrgPtr; +#ifdef DISPLAY_180_DEGREE + DataLinePrt = Picture; +#endif + for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line + { + // SPI (0x04, 0x03) + epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); + k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; + for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // check every bit in the line + { + TempByte = (*Picture++); +#ifdef DISPLAY_180_DEGREE + DataLineEven[j] = ((TempByte & 0x80) ? BLACK3 : NOTHING) + | ((TempByte & 0x20) ? BLACK2 : NOTHING ) + | ((TempByte & 0x08) ? BLACK1 : NOTHING ) + | ((TempByte & 0x02) ? BLACK0 : NOTHING ); + + DataLineOdd[k--] = ((TempByte & 0x01) ? BLACK3 : NOTHING) + | ((TempByte & 0x04) ? BLACK2 : NOTHING ) + | ((TempByte & 0x10) ? BLACK1 : NOTHING ) + | ((TempByte & 0x40) ? BLACK0 : NOTHING ); + DataLinePrt--; +#else + DataLineOdd[j] = ((TempByte & 0x80) ? BLACK3 : NOTHING) + | ((TempByte & 0x20) ? BLACK2 : NOTHING ) + | ((TempByte & 0x08) ? BLACK1 : NOTHING ) + | ((TempByte & 0x02) ? BLACK0 : NOTHING ); + + DataLineEven[k--] = ((TempByte & 0x01) ? BLACK3 : NOTHING) + | ((TempByte & 0x04) ? BLACK2 : NOTHING ) + | ((TempByte & 0x10) ? BLACK1 : NOTHING ) + | ((TempByte & 0x40) ? BLACK0 : NOTHING ); +#endif + } +#ifdef DISPLAY_180_DEGREE + Picture = DataLinePrt; +#endif + DataLineScan[(i>>2)] = ScanTable[(i%4)]; + // SPI (0x0a, line data....) + epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); + + epd_SPI_Send_Byte(0x02, 0x2F); + + DataLineScan[(i>>2)] = 0; + } +#if(!_GaugeFrameTimeMark) + if(COG_Parameters[EPD_Type_Index].FrameTime>0) + { + while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); + } +#endif + //TestPin2Trigger(); + Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; + cnt++; + }while (StageTime>Currentframe); +// TestPin2Trigger(); + while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); +// TestPin2Trigger(); +// TestPinTrigger(); +} + +//#pragma GCC optimize ("-O3") +static void Display_Stage_4 (uint8_t *Picture) +{ + uint16_t i, j,k; // general counters + uint8_t TempByte; // Temporary storage for image data check + uint16_t StartClock; +#ifdef DISPLAY_180_DEGREE + uint8_t *DataLinePrt; + DisplayOrgPtr = (Picture+(uint32_t)((COG_Parameters[EPD_Type_Index].VERTICAL-1)*COG_Parameters[EPD_Type_Index].HORIZONTAL)); +#else + DisplayOrgPtr = Picture; +#endif + Currentframe = (uint32_t)COG_Parameters[EPD_Type_Index].FrameTime; + cnt = 0; +// TestPinTrigger(); + + StartClock = epd_GetCurrentTimeTick(); + do + { +// TestPin2Trigger(); + Picture = DisplayOrgPtr; +#ifdef DISPLAY_180_DEGREE + DataLinePrt = Picture; +#endif + for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line + { + // SPI (0x04, ...) + epd_SPI_Send_Byte(0x04, COG_Parameters[EPD_Type_Index].VoltageLevel); + k = COG_Parameters[EPD_Type_Index].HORIZONTAL-1; + for (j = 0; j < COG_Parameters[EPD_Type_Index].HORIZONTAL; j++) // check every bit in the line + { + TempByte =(*Picture++); +#ifdef DISPLAY_180_DEGREE + DataLineEven[j] = ((TempByte & 0x80) ? WHITE3 : BLACK3 ) + | ((TempByte & 0x20) ? WHITE2 : BLACK2 ) + | ((TempByte & 0x08) ? WHITE1 : BLACK1 ) + | ((TempByte & 0x02) ? WHITE0 : BLACK0 ); + + DataLineOdd[k--] = ((TempByte & 0x01) ? WHITE3 : BLACK3 ) + | ((TempByte & 0x04) ? WHITE2 : BLACK2 ) + | ((TempByte & 0x10) ? WHITE1 : BLACK1 ) + | ((TempByte & 0x40) ? WHITE0 : BLACK0 ); + DataLinePrt--; +#else + DataLineOdd[j] = ((TempByte & 0x80) ? WHITE3 : BLACK3 ) + | ((TempByte & 0x20) ? WHITE2 : BLACK2 ) + | ((TempByte & 0x08) ? WHITE1 : BLACK1 ) + | ((TempByte & 0x02) ? WHITE0 : BLACK0 ); + + DataLineEven[k--] = ((TempByte & 0x01) ? WHITE3 : BLACK3 ) + | ((TempByte & 0x04) ? WHITE2 : BLACK2 ) + | ((TempByte & 0x10) ? WHITE1 : BLACK1 ) + | ((TempByte & 0x40) ? WHITE0 : BLACK0 ); +#endif + } +#ifdef DISPLAY_180_DEGREE + Picture = DataLinePrt; +#endif + DataLineScan[(i>>2)] = ScanTable[(i%4)]; + // SPI (0x0a, line data....) + epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); + + epd_SPI_Send_Byte(0x02, 0x2F); + + DataLineScan[(i>>2)] = 0; + } +#if(!_GaugeFrameTimeMark) + if(COG_Parameters[EPD_Type_Index].FrameTime>0) + { + while(Currentframe>(epd_GetCurrentTimeTick() - StartClock)); + } +#endif + //TestPin2Trigger(); + Currentframe=(uint32_t)(epd_GetCurrentTimeTick() - StartClock)+COG_Parameters[EPD_Type_Index].FrameTime ; + cnt++; + }while (StageTime>Currentframe); + +// TestPin2Trigger(); + while(StageTime>(epd_GetCurrentTimeTick() - StartClock)); +// TestPin2Trigger(); +// TestPinTrigger(); +} + +static void Display_Nothing (void) +{ + uint16_t i; // general counters + + for (i = 0; i < COG_Parameters[EPD_Type_Index].HORIZONTAL; i++) // make every bit in the line white + { + DataLineEven[i] = 0x00; + DataLineOdd[i] = 0x00; + } + + for (i = 0; i < COG_Parameters[EPD_Type_Index].VERTICAL; i++) // for every line + { + epd_SPI_Send_Byte(0x04, 0x03); + DataLineScan[(i>>2)] = ScanTable[(i%4)]; + // SPI (0x0a, line data....) + epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); + + epd_SPI_Send_Byte(0x02, 0x2F); + } +} + +static void Dummy_line(void) +{ + uint16_t i; + + for (i = 0; i < COG_Parameters[EPD_Type_Index].DataLineSize; i++) + { + COG_Line.uint8[i] = 0x00; + } + + epd_SPI_Send_Byte(0x04, 0x03); + + // SPI (0x0a, line data....) + epd_SPI_Send(0x0a, (uint8_t *)&COG_Line.uint8, COG_Parameters[EPD_Type_Index].DataLineSize); + + epd_SPI_Send_Byte(0x02, 0x2F); +} + + +/****************************************************************************** + * Public functions + *****************************************************************************/ +void epd_HwInit(void) +{ + epd_InitDisplayHardware(); +} + +void epd_PowerOn(void) +{ + epd_discharge_low(); + epd_rst_low(); + epd_cs_low(); + epd_spi_init(); + + epd_pwm_active(5); + + epd_panelon_on(); + + epd_pwm_active(10); + + epd_cs_high(); + + //epd_border_high(); + + epd_rst_high(); + + epd_pwm_active(5); + + epd_rst_low(); + + epd_pwm_active(5); + + epd_rst_high(); + + epd_pwm_active(5); +} + +void epd_InitializeDriver(uint8_t EPDIndex) +{ + uint8_t SendBuffer[2]; + uint16_t k; + + EPD_Type_Index = EPDIndex; + + //Data Line Clear + for (k = 0; k <= __LineDataSize; k ++) + { + COG_Line.uint8[k] = 0x00; + } + Driver_TypeSelect(EPDIndex); + k = 0; + + SetTemperature_Factor(EPDIndex); + + /*while (DRIVERBUSY_Get()) + { + delayT32B0Us(500); + if((k++)>=1000) return;//wait 500 ms + } + */ + + // SPI (0x01, 0x0000, 0x0000, 0x01ff, 0xe000) + epd_SPI_Send(0x01, (uint8_t *)&COG_Parameters[EPDIndex].ChannelSelect, 8); + + epd_SPI_Send_Byte(0x06, 0xff); + epd_SPI_Send_Byte(0x07, 0x9d); + epd_SPI_Send_Byte(0x08, 0x00); + + // SPI (0x09, 0xd000) + SendBuffer[0] = 0xd0; + SendBuffer[1] = 0x00; + epd_SPI_Send(0x09, SendBuffer, 2); + + epd_SPI_Send_Byte(0x04,COG_Parameters[EPDIndex].VoltageLevel); + + epd_SPI_Send_Byte(0x03, 0x01); + epd_SPI_Send_Byte(0x03, 0x00); + + epd_pwm_active(5); + + epd_SPI_Send_Byte(0x05, 0x01); + + epd_pwm_active(30); + + epd_SPI_Send_Byte(0x05, 0x03); + epd_delay_ms(30); + epd_SPI_Send_Byte(0x05, 0x0f); + epd_delay_ms(30); + epd_SPI_Send_Byte(0x02, 0x24); +} + +void epd_Display (uint8_t *pNewImg, uint8_t *pPrevImg) +{ + //COG Process - update display in four steps + Display_Stage_1(pPrevImg); + Display_Stage_2(pPrevImg); + Display_Stage_3(pNewImg); + Display_Stage_4(pNewImg); +} + +void epd_PowerOff (void) +{ + Display_Nothing(); + Dummy_line(); + epd_delay_ms(25); + + //border_low(); + //epd_delay_ms(_30ms); + //border_high(); + + epd_SPI_Send_Byte(0x03, 0x01); + epd_SPI_Send_Byte(0x02, 0x05); + epd_SPI_Send_Byte(0x05, 0x0E); + epd_SPI_Send_Byte(0x05, 0x02); + epd_SPI_Send_Byte(0x04, 0x0C); + epd_delay_ms(120); + epd_SPI_Send_Byte(0x05, 0x00); + epd_SPI_Send_Byte(0x07, 0x0D); + epd_SPI_Send_Byte(0x04, 0x50); + epd_delay_ms(40); + epd_SPI_Send_Byte(0x04, 0xA0); + epd_delay_ms(40); + epd_SPI_Send_Byte(0x04, 0x00); + + epd_rst_low(); + epd_cs_low(); + epd_spi_detach(); + epd_panelon_off(); + + //epd_border_low(); + + epd_discharge_high(); + epd_delay_ms(150); + epd_discharge_low(); +} + + + diff -r 000000000000 -r f6507ae3df93 Display_COG_Process.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Display_COG_Process.h Sun Apr 07 18:35:52 2013 +0000 @@ -0,0 +1,120 @@ +// Copyright 2013 Pervasive Displays, Inc. +// +// 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. + +#ifndef __Display_COG_Process_H_ +#define __Display_COG_Process_H_ + +/****************************************************************************** + * Includes + *****************************************************************************/ + + #include "bsp.h" + +/****************************************************************************** + * Defines and typedefs + *****************************************************************************/ +#define BLACK0 (0x03) +#define BLACK1 (0x0C) +#define BLACK2 (0x30) +#define BLACK3 (0xc0) +#define WHITE0 (0x02) +#define WHITE1 (0x08) +#define WHITE2 (0x20) +#define WHITE3 (0x80) + +#define NOTHING (0x00) +#define SCANON (0xC0) +#define __LineDataSize 111 + +/* +enum +{ + _5ms, + _10ms, + _25ms, + _30ms, + _40ms, + _120ms, + _150ms, + _300ms +}; +*/ + +typedef enum +{ + EPDType_144 = 0, //1.44" display + EPDType_200 = 1, //2.0" display + EPDType_270 = 2 //2.7" display +} EPDType_t; +#define EPD_TYPE_144 0 +#define EPD_TYPE_200 1 +#define EPD_TYPE_270 2 + +typedef struct +{ + uint8_t Even[16]; + uint8_t Scan[24]; + uint8_t Odd [16]; +} COG_144_LineData_t; + +typedef struct +{ + uint8_t Even[25]; + uint8_t Scan[24]; + uint8_t Odd [25]; + uint8_t DummyData; +} COG_20_LineData_t; + +typedef struct +{ + uint8_t Even[33]; + uint8_t Scan[44]; + uint8_t Odd [33]; + uint8_t DummyData; +} COG_27_LineData_t; + +typedef union +{ + union + { + COG_144_LineData_t COG_144LineData; + COG_20_LineData_t COG_20LineData; + COG_27_LineData_t COG_27LineData; + } LineDatas; + uint8_t uint8[__LineDataSize]; +} COG_LineDataPacket_t; + +typedef struct +{ + uint8_t ChannelSelect[8]; + uint8_t VoltageLevel; + uint16_t HORIZONTAL; + uint16_t VERTICAL; + uint8_t DataLineSize; + uint16_t FrameTime; + uint16_t StageTime; +} COG_Parameters_t; + +extern const COG_Parameters_t COG_Parameters[3]; + +/****************************************************************************** + * Prototypes + *****************************************************************************/ +void epd_HwInit(void); +void epd_PowerOn(void); +void epd_InitializeDriver(uint8_t EPDIndex); +void epd_Display(uint8_t *pNewImg, uint8_t *pPrevImg); +void epd_PowerOff(void); + +#endif //__Display_COG_Process_H_ diff -r 000000000000 -r f6507ae3df93 Display_Controller.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Display_Controller.c Sun Apr 07 18:35:52 2013 +0000 @@ -0,0 +1,40 @@ +// Copyright 2013 Pervasive Displays, Inc. +// +// 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. + +/****************************************************************************** + * Includes + *****************************************************************************/ +//#include "driver_config.h" +//#include "type.h" +//#include "gpio.h" +#include "Display_Controller.h" + +/****************************************************************************** + * Global Functions + *****************************************************************************/ + +void epd_DisplayImg(EPDType_t EPDType, uint8_t *pNewImg, uint8_t *pPrevImg) +{ + //always initialize display (has been powered off before) + epd_HwInit(); + epd_PowerOn(); + epd_InitializeDriver(EPDType); + + //display new picture, but first remove old one + epd_Display(pNewImg, pPrevImg); + + //power down display - picture still displayed + epd_PowerOff(); +} + diff -r 000000000000 -r f6507ae3df93 Display_Controller.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Display_Controller.h Sun Apr 07 18:35:52 2013 +0000 @@ -0,0 +1,34 @@ +// Copyright 2013 Pervasive Displays, Inc. +// +// 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. + +#ifndef __Display_Controller_H_ +#define __Display_Controller_H_ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "bsp.h" +#include "Display_COG_Process.h" + +/****************************************************************************** + * Defines and typedefs + *****************************************************************************/ +#define DISPLAY_IN_USE EPD_TYPE_270 + +/****************************************************************************** + * Prototypes + *****************************************************************************/ +void epd_DisplayImg(EPDType_t EPDType, uint8_t *pNewImg, uint8_t *pPrevImg); + +#endif //__Display_Controller_H_ diff -r 000000000000 -r f6507ae3df93 Display_Hardware_Driver.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Display_Hardware_Driver.c Sun Apr 07 18:35:52 2013 +0000 @@ -0,0 +1,258 @@ +// Copyright 2013 Pervasive Displays, Inc. +// +// 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. + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "Display_Hardware_Driver.h" + + +/****************************************************************************** + * Public functions + *****************************************************************************/ +void epd_cs_high(void) +{ + // CS_SET_HIGH; + bsp_pinOut(BSP_PIN_6, 1); +} + +void epd_cs_low(void) +{ + // CS_SET_LOW; + bsp_pinOut(BSP_PIN_6, 0); +} + +void epd_rst_high(void) +{ + // RST_SET_HIGH; + bsp_pinOut(BSP_PIN_12, 1); +} + +void epd_rst_low(void) +{ + // RST_SET_LOW; + bsp_pinOut(BSP_PIN_12, 0); +} + +void epd_discharge_high(void) +{ + // DISCHARGE_SET_HIGH; + bsp_pinOut(BSP_PIN_14, 1); +} + +void epd_discharge_low(void) +{ + // DISCHARGE_SET_LOW; + bsp_pinOut(BSP_PIN_14, 0); +} + +void epd_panelon_off(void) +{ + // PANELON_SET_LOW; + bsp_pinOut(BSP_PIN_13, 0); +} + +void epd_panelon_on(void) +{ + // PANELON_SET_HIGH; + bsp_pinOut(BSP_PIN_13, 1); +} + +void epd_border_high(void) +{ + // BORDER_SET_HIGH; +} + +void epd_border_low(void) +{ + // BORDER_SET_LOW; +} + +void epd_delay_ms(uint32_t Time) +{ + bsp_delayMs(Time); +} + +int16_t epd_get_temperature(void) +{ + return bsp_getTemp(); +} + +uint32_t epd_GetCurrentTimeTick(void) +{ + return bsp_getMsTicks(); +} + +//****************************************************************** +//PWM Configuration/Control +//****************************************************************** +#if 0 +volatile uint32_t period = 500; //96Khz PWM frequency + +void epd_pwm_disable(void) +{ + disable_timer16(1); + LPC_IOCON->PIO1_9 &= 0xFC;//Disable PWM,set general IO + PWM_DIR_OUT(); + PWM_SET_LOW(); +} + +void epd_pwm_active(void) +{ + PWM_SET_HIGH(); + /* Initialize the PWM in timer32_1 enabling match0 output */ + init_timer16PWM(1, period, MATCH0,0); + setMatch_timer16PWM (1, 1, period/8); + enable_timer16(1); +} +#endif +void epd_pwm_active(uint16_t delayInMs) +{ + uint16_t numOfIterations; + + numOfIterations = delayInMs * 100; + // PWM_DIR_OUT; + bsp_pinMode(BSP_PIN_11, BSP_PINMODE_OUTPUT); + for(; numOfIterations > 0; numOfIterations--) + { + // PWM_SET_HIGH; + bsp_pinOut(BSP_PIN_11, 1); + bsp_delayUs(5); //100kHz (96kHz ideal) + // PWM_SET_LOW; + bsp_pinOut(BSP_PIN_11, 0); + bsp_delayUs(5); + } +} + + +//****************************************************************** +//SPI Configuration +//****************************************************************** +void epd_spi_detach(void) +{ +#if 0 + LPC_IOCON->PIO0_8 &= 0xFC;; /* SSP I/O config */ + SPIMISO_DIR_OUT(); + SPIMISO_Set(Low); + + LPC_IOCON->PIO0_9 &= 0xFC; /* SSP MOSI */ + SPIMOSI_DIR_OUT(); + SPIMOSI_Set(Low); + + LPC_IOCON->PIO2_11 &= 0xFC; + SPICLK_DIR_OUT(); + SPICLK_Set(Low); +#endif +} +void epd_spi_init (void) +{ + bsp_spiInit(); +//SSP_IOConfig( SSP_PORT ); /* initialize SSP port */ +//SSP_Init( SSP_PORT ); +} + +void epd_SPI_Send (unsigned char Register, unsigned char *Data, unsigned Length) +{ + uint8_t buf[2]; + + epd_cs_low(); + buf[0] = 0x70; + buf[1] = Register; + bsp_writeToDisplay(buf, 2); + epd_cs_high(); + bsp_delayUs(10); + + epd_cs_low(); + buf[0] = 0x72; + bsp_writeToDisplay(buf, 1); + bsp_writeToDisplay(Data, Length); + epd_cs_high(); + bsp_delayUs(10); +} + + + +void epd_SPI_Send_Byte (uint8_t Register, uint8_t Data) +{ + uint8_t buf[2]; + + epd_cs_low(); + buf[0] = 0x70; + buf[1] = Register; + bsp_writeToDisplay(buf, 2); + epd_cs_high(); + bsp_delayUs(10); + + epd_cs_low(); + buf[0] = 0x72; + buf[1] = Data; + bsp_writeToDisplay(buf, 2); + epd_cs_high(); + bsp_delayUs(10); +} + +void epd_InitDisplayHardware(void) +{ + // RST_DIR_OUT; + bsp_pinMode(BSP_PIN_12, BSP_PINMODE_OUTPUT); + // DISCHARGE_DIR_OUT; + bsp_pinMode(BSP_PIN_14, BSP_PINMODE_OUTPUT); + // CS_DIR_OUT; + bsp_pinMode(BSP_PIN_6, BSP_PINMODE_OUTPUT); + // PANELON_DIR_OUT; + bsp_pinMode(BSP_PIN_13, BSP_PINMODE_OUTPUT); + // DRIVERBUSY_DIR_IN; + bsp_pinMode(BSP_PIN_7, BSP_PINMODE_INPUT); + // BORDER_DIR_OUT; + + + epd_panelon_off(); + epd_spi_init(); + epd_cs_low(); + // epd_pwm_low(); + epd_pwm_active(0); //set output low + epd_rst_low(); + epd_discharge_low(); + +// TESTPin_DIR_OUT(); +// TESTPin2_DIR_OUT(); +} + +//************************************************************************ +void TestPinLow(void) +{ +// TESTPin_Set(0); +} +void TestPinHigh(void) +{ +// TESTPin_Set(1); +} +void TestPinTrigger(void) +{ +// if(TESTPin_Get())TestPinLow(); +// else TestPinHigh(); +} +void TestPin2Low(void) +{ +// TESTPin2_Set(0); +} +void TestPin2High(void) +{ +// TESTPin2_Set(1); +} +void TestPin2Trigger(void) +{ +// if(TESTPin2_Get())TestPin2Low(); +// else TestPin2High(); +} diff -r 000000000000 -r f6507ae3df93 Display_Hardware_Driver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Display_Hardware_Driver.h Sun Apr 07 18:35:52 2013 +0000 @@ -0,0 +1,102 @@ +// Copyright 2013 Pervasive Displays, Inc. +// +// 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. + +#ifndef __DISPLAY_HARDWARE_DRIVER_H_ +#define __DISPLAY_HARDWARE_DRIVER_H_ + +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include "bsp.h" + + +/****************************************************************************** + * Defines and typedefs + *****************************************************************************/ + +//Pin 12 on Serial Expansion Connector +// #define RST_DIR_OUT SEC14_PIN12_SET_OUTP +// #define RST_SET_HIGH SEC14_PIN12_SET_HIGH +// #define RST_SET_LOW SEC14_PIN12_SET_LOW + +//Pin 14 on Serial Expansion Connector +// #define DISCHARGE_DIR_OUT SEC14_PIN14_SET_OUTP +// #define DISCHARGE_SET_HIGH SEC14_PIN14_SET_HIGH +// #define DISCHARGE_SET_LOW SEC14_PIN14_SET_LOW + +//Pin 6 on Serial Expansion Connector +// #define CS_DIR_OUT SEC14_PIN6_SET_OUTP +// #define CS_SET_HIGH SEC14_PIN6_SET_HIGH +// #define CS_SET_LOW SEC14_PIN6_SET_LOW + +//Pin 13 on Serial Expansion Connector +// #define PANELON_DIR_OUT SEC14_PIN13_SET_OUTP +// #define PANELON_SET_HIGH SEC14_PIN13_SET_HIGH +// #define PANELON_SET_LOW SEC14_PIN13_SET_LOW + +//Pin 7 on Serial Expansion Connector +// #define DRIVERBUSY_DIR_IN SEC14_PIN7_SET_INP +// #define DRIVERBUSY_GET SEC14_PIN7_INP + +//Not implemented +// #define BORDER_DIR_OUT +// #define BORDER_SET_HIGH +// #define BORDER_SET_LOW + +//Pin 11 on Serial Expansion Connector +// #define PWM_DIR_OUT SEC14_PIN11_SET_OUTP +// #define PWM_SET_HIGH SEC14_PIN11_SET_HIGH +// #define PWM_SET_LOW SEC14_PIN11_SET_LOW + + +/****************************************************************************** + * Prototypes + *****************************************************************************/ +void epd_cs_high(void); +void epd_cs_low(void); +void epd_rst_high(void); +void epd_rst_low(void); +void epd_discharge_high(void); +void epd_discharge_low(void); +void epd_panelon_off(void); +void epd_panelon_on(void); + +void epd_pwm_active(uint16_t delayInMs); + +void epd_border_high(void); +void epd_border_low(void); + +void epd_TestPinLow(void); +void epd_TestPinHigh(void); +void epd_TestPinTrigger(void); + +void epd_TestPin2Low(void); +void epd_TestPin2High(void); +void epd_TestPin2Trigger(void); + +void epd_delay_ms(uint32_t Time); +int16_t epd_get_temperature(void); +uint32_t epd_GetCurrentTimeTick(void); + +/***************************************************************************/ +void epd_spi_detach(void); +void epd_spi_init (void); +void epd_SPI_Send (unsigned char Register, unsigned char *Data, unsigned Length); +void epd_SPI_Send_Byte (uint8_t Register, uint8_t Data); +void epd_InitDisplayHardware (void); + +/****************************************************************************/ + +#endif //__DISPLAY_HARDWARE_DRIVER_H_ diff -r 000000000000 -r f6507ae3df93 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Sun Apr 07 18:35:52 2013 +0000 @@ -0,0 +1,37 @@ +# Makefile - Build the epaper software +# +# Copyright (C) 2013 Paul Boddie +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +LIBUBB = ../ben-blinkenlights/libubb +SYSLIBS = ../openwrt-xburst/staging_dir/target-mipsel_eglibc-2.15/usr/lib + +ARCH = mipsel-openwrt-linux +CC = $(ARCH)-gcc + +CFLAGS = -g -Wall -fPIC -march=mips32 -I$(LIBUBB)/include # -DDEBUG=1 +LDFLAGS = -lubb -L$(LIBUBB) #-static #-L$(SYSLIBS) + +TARGET = test +SRC = test.c Display_COG_Process.c Display_Controller.c Display_Hardware_Driver.c +OBJ = $(SRC:.c=.o) + +.PHONY: all clean distclean + +all: $(TARGET) + +clean: + rm -f $(OBJ) $(TARGET) + +distclean: clean + echo "Nothing else to clean." + +$(TARGET): $(OBJ) + $(CC) $(LDFLAGS) $< -o $@ + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@