|
|
/*------------------------------------------------------------------------------
|
|
|
-- This file is a part of the libuc, microcontroler library
|
|
|
-- Copyright (C) 2013, Alexis Jeandet
|
|
|
--
|
|
|
-- 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 3 of the License, or
|
|
|
-- (at your option) any later version.
|
|
|
--
|
|
|
-- This program is distributed in the hope that it will be useful,
|
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
-- GNU General Public License for more details.
|
|
|
--
|
|
|
-- You should have received a copy of the GNU General Public License
|
|
|
-- along with this program; if not, write to the Free Software
|
|
|
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
-------------------------------------------------------------------------------
|
|
|
-- Author : Alexis Jeandet
|
|
|
-- Mail : alexis.jeandet@member.fsf.org
|
|
|
-------------------------------------------------------------------------------*/
|
|
|
#include <ssd2119.h>
|
|
|
#include <stdio.h>
|
|
|
#include <stddef.h>
|
|
|
#include <core.h>
|
|
|
#include <math.h>
|
|
|
|
|
|
#ifdef __OPTIMIZED_MATH
|
|
|
#include <optimised_math.h>
|
|
|
#endif
|
|
|
|
|
|
#define _delay_(del) for(volatile int _d_e_l_=0;_d_e_l_<(del);_d_e_l_++);
|
|
|
|
|
|
#define ilipaintLine(LCD,X,Y,W,buffer,buffsize) \
|
|
|
for(int l=0;l<1;l++)\
|
|
|
{\
|
|
|
ssd2119setFrame(LCD,X,Y,W,1);\
|
|
|
int rem=(W)%buffsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(buffer,rem);\
|
|
|
for(int i=rem;i<(W);i+=buffsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(buffer,buffsize);\
|
|
|
}\
|
|
|
}
|
|
|
|
|
|
#define ilipaintHLineWithCont(LCD,X,Y,W,ContSz,bufferInt,buffIntsize,bufferCont,buffContsize) \
|
|
|
for(int l=0;l<1;l++)\
|
|
|
{\
|
|
|
ssd2119setFrame(LCD,X,Y,W,1);\
|
|
|
int rem=(ContSz)%buffContsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(bufferCont,rem);\
|
|
|
for(int i=rem;i<(ContSz);i+=buffContsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(bufferCont,buffContsize);\
|
|
|
}\
|
|
|
if((2*ContSz)<W) \
|
|
|
{\
|
|
|
rem=(W-(2*ContSz))%buffIntsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(bufferInt,rem);\
|
|
|
for(int i=rem;i<(W-(2*ContSz));i+=buffIntsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(bufferInt,buffIntsize);\
|
|
|
}\
|
|
|
}\
|
|
|
rem=(ContSz)%buffContsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(bufferCont,rem);\
|
|
|
for(int i=rem;i<(ContSz);i+=buffContsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(bufferCont,buffContsize);\
|
|
|
}\
|
|
|
}\
|
|
|
|
|
|
|
|
|
#define ilipaintVLineWithCont(LCD,X,Y,H,ContSz,bufferInt,buffIntsize,bufferCont,buffContsize) \
|
|
|
for(int l=0;l<1;l++)\
|
|
|
{\
|
|
|
ssd2119setFrame(LCD,X,Y,1,H);\
|
|
|
int rem=(ContSz)%buffContsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(bufferCont,rem);\
|
|
|
for(int i=rem;i<(ContSz);i+=buffContsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(bufferCont,buffContsize);\
|
|
|
}\
|
|
|
if((2*ContSz)<H) \
|
|
|
{\
|
|
|
rem=(H-(2*ContSz))%buffIntsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(bufferInt,rem);\
|
|
|
for(int i=rem;i<(H-(2*ContSz));i+=buffIntsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(bufferInt,buffIntsize);\
|
|
|
}\
|
|
|
}\
|
|
|
rem=(ContSz)%buffContsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(bufferCont,rem);\
|
|
|
for(int i=rem;i<(ContSz);i+=buffContsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(bufferCont,buffContsize);\
|
|
|
}\
|
|
|
}\
|
|
|
|
|
|
|
|
|
#define ilipaintHalfTopVLineWithCont(LCD,X,Y,H,ContSz,bufferInt,buffIntsize,bufferCont,buffContsize) \
|
|
|
for(int l=0;l<1;l++)\
|
|
|
{\
|
|
|
ssd2119setFrame(LCD,X,Y,1,H);\
|
|
|
int rem=(ContSz)%buffContsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(bufferCont,rem);\
|
|
|
for(int i=rem;i<(ContSz);i+=buffContsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(bufferCont,buffContsize);\
|
|
|
}\
|
|
|
if(ContSz<H) \
|
|
|
{\
|
|
|
rem=(H-ContSz)%buffIntsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(bufferInt,rem);\
|
|
|
for(int i=rem;i<(H-ContSz);i+=buffIntsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(bufferInt,buffIntsize);\
|
|
|
}\
|
|
|
}\
|
|
|
}\
|
|
|
|
|
|
|
|
|
#define ilipaintHalfBottomVLineWithCont(LCD,X,Y,H,ContSz,bufferInt,buffIntsize,bufferCont,buffContsize) \
|
|
|
for(int l=0;l<1;l++)\
|
|
|
{\
|
|
|
ssd2119setFrame(LCD,X,Y,1,H);\
|
|
|
int rem;\
|
|
|
if(ContSz<H) \
|
|
|
{\
|
|
|
rem=(H-ContSz)%buffIntsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(bufferInt,rem);\
|
|
|
for(int i=rem;i<(H-ContSz);i+=buffIntsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(bufferInt,buffIntsize);\
|
|
|
}\
|
|
|
}\
|
|
|
rem=(ContSz)%buffContsize;\
|
|
|
if(rem)LCD->interface->writeGRAM(bufferCont,rem);\
|
|
|
for(int i=rem;i<(ContSz);i+=buffContsize)\
|
|
|
{\
|
|
|
LCD->interface->writeGRAM(bufferCont,buffContsize);\
|
|
|
}\
|
|
|
}\
|
|
|
|
|
|
|
|
|
void ssd2119setGRAMaddress(LCD_t* LCD,uint16_t Haddress,uint16_t Vaddress)
|
|
|
{
|
|
|
LCD->interface->writereg(SSD2119_REGISTER_X_RAM_ADDR,Haddress);
|
|
|
LCD->interface->writereg(SSD2119_REGISTER_Y_RAM_ADDR,Vaddress);
|
|
|
}
|
|
|
|
|
|
void ssd2119refreshenable(struct LCD_t* LCD,int enable)
|
|
|
{
|
|
|
if(enable)
|
|
|
{
|
|
|
//LCD->interface->writereg(ssd2119_REGISTER_ENTRYMODE,0x1018);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//LCD->interface->writereg(ssd2119_REGISTER_ENTRYMODE,0x1008);
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void ssd2119setFrame(LCD_t* LCD,uint16_t X,uint16_t Y,uint16_t W,uint16_t H)
|
|
|
{
|
|
|
LCD->interface->writereg(SSD2119_REGISTER_X_RAM_ADDR,(uint32_t)X);
|
|
|
LCD->interface->writereg(SSD2119_REGISTER_Y_RAM_ADDR,(uint32_t)Y);
|
|
|
LCD->interface->writereg(SSD2119_REGISTER_H_RAM_START,(uint32_t)X);
|
|
|
LCD->interface->writereg(SSD2119_REGISTER_H_RAM_END,(uint32_t)(W+X-1));
|
|
|
LCD->interface->writereg(SSD2119_REGISTER_V_RAM_POS,(((uint32_t)(Y+H-1))<<8) + (uint32_t)Y);
|
|
|
}
|
|
|
|
|
|
void ssd2119paint(LCD_t* LCD,void* buffer,uint16_t Xpos,uint16_t Ypos,uint16_t Width,uint16_t Height)
|
|
|
{
|
|
|
if((LCD!=NULL) && (LCD->interface!=NULL) && (LCD->interface->writeGRAM!=NULL) && (LCD->width>(Xpos+Width)) && (LCD->height>(Ypos+Height)))
|
|
|
{
|
|
|
ssd2119setFrame(LCD,Xpos,Ypos,Width,Height);
|
|
|
LCD->interface->writeGRAM(buffer,Width*Height);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void ssd2119paintFilCirc(LCD_t* LCD,uint16_t Xpos,uint16_t Ypos,uint16_t r,uint32_t contColor,uint16_t contSz,uint32_t fillColor)
|
|
|
{
|
|
|
//Based on the mid point circle algorithm from Wikipedia
|
|
|
//http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
|
|
|
uint16_t innerbuffer[16];
|
|
|
uint16_t outterbuffer[16];
|
|
|
for(int i=0;i<16;i++)innerbuffer[i]=fillColor;
|
|
|
for(int i=0;i<16;i++)outterbuffer[i]=contColor;
|
|
|
if(contSz<r)
|
|
|
{
|
|
|
int error = -r,error_int = -r+contSz;
|
|
|
int x = r,x_int=r-contSz;
|
|
|
int y = 0,y_int=0;
|
|
|
while (x >= y)
|
|
|
{
|
|
|
ilipaintHLineWithCont(LCD,(Xpos-x),(Ypos+y),(2*x),(x-x_int),innerbuffer,16,outterbuffer,16);
|
|
|
ilipaintHLineWithCont(LCD,(Xpos-x),(Ypos-y),(2*x),(x-x_int),innerbuffer,16,outterbuffer,16);
|
|
|
ilipaintHalfTopVLineWithCont(LCD,(Xpos+y),(Ypos-x),(x),(x-x_int),innerbuffer,16,outterbuffer,16);
|
|
|
ilipaintHalfTopVLineWithCont(LCD,(Xpos-y),(Ypos-x),(x),(x-x_int),innerbuffer,16,outterbuffer,16);
|
|
|
ilipaintHalfBottomVLineWithCont(LCD,(Xpos-y),(Ypos),(x),(x-x_int),innerbuffer,16,outterbuffer,16);
|
|
|
ilipaintHalfBottomVLineWithCont(LCD,(Xpos+y),(Ypos),(x),(x-x_int),innerbuffer,16,outterbuffer,16);
|
|
|
error += y;
|
|
|
++y;
|
|
|
error += y;
|
|
|
error_int += y_int;
|
|
|
++y_int;
|
|
|
error_int += y_int;
|
|
|
if(error >= 0)
|
|
|
{
|
|
|
error -= x;
|
|
|
--x;
|
|
|
error -= x;
|
|
|
}
|
|
|
if(error_int >= 0)
|
|
|
{
|
|
|
error_int -= x_int;
|
|
|
--x_int;
|
|
|
error_int -= x_int;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void ssd2119paintFilCirc_old(LCD_t* LCD,uint16_t Xpos,uint16_t Ypos,uint16_t r,uint32_t contColor,uint16_t contSz,uint32_t fillColor)
|
|
|
{
|
|
|
if(contSz<r)
|
|
|
{
|
|
|
uint16_t innerbuffer[16];
|
|
|
uint16_t outterbuffer[16];
|
|
|
int32_t rr=(r*r),rr2=((r-contSz)*(r-contSz)),contSz2,Val1,Val2,X1,W,rem;
|
|
|
for(int i=0;i<16;i++)innerbuffer[i]=fillColor;
|
|
|
for(int i=0;i<16;i++)outterbuffer[i]=contColor;
|
|
|
/* Y = b +/- sqrt[r^2 - (x - a)^2] */
|
|
|
for(int32_t line=-r;line<r;line++)
|
|
|
{
|
|
|
#ifdef __OPTIMIZED_MATH
|
|
|
Val1 = (uint32_t)optimised_sqrt((float32_t)(rr - (line*line)) );
|
|
|
Val2 = (uint32_t)optimised_sqrt((float32_t)(rr2 - (line*line)) );
|
|
|
#else
|
|
|
Val1 = sqrt( (double)(rr - ((line)*(line))) );
|
|
|
Val2 = sqrt( (double)(rr2 - ((line)*(line))) );
|
|
|
#endif
|
|
|
X1=Xpos - Val1;
|
|
|
contSz2= Val1-Val2;
|
|
|
ssd2119setFrame(LCD,X1,line+Ypos,2*Val1,1);
|
|
|
rem=(contSz2)%16;
|
|
|
if(rem)LCD->interface->writeGRAM(outterbuffer,rem);
|
|
|
for(int i=rem;i<(contSz2);i+=16)
|
|
|
{
|
|
|
LCD->interface->writeGRAM(outterbuffer,16);
|
|
|
}
|
|
|
|
|
|
W=2*Val1;
|
|
|
if(W>(2*contSz2))
|
|
|
{
|
|
|
W-=2*contSz2;
|
|
|
rem=(W)%16;
|
|
|
if(rem)LCD->interface->writeGRAM(innerbuffer,rem);
|
|
|
for(int i=rem;i<(W);i+=16)
|
|
|
{
|
|
|
LCD->interface->writeGRAM(innerbuffer,16);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
rem=(contSz2)%16;
|
|
|
if(rem)LCD->interface->writeGRAM(outterbuffer,rem);
|
|
|
for(int i=rem;i<(contSz2);i+=16)
|
|
|
{
|
|
|
LCD->interface->writeGRAM(outterbuffer,16);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ssd2119paintFilRect(LCD_t* LCD,uint16_t Xpos,uint16_t Ypos,uint16_t w,uint16_t h,uint32_t contColor,uint16_t contSz,uint32_t fillColor)
|
|
|
{
|
|
|
ssd2119setFrame(LCD,Xpos,Ypos,w,h);
|
|
|
uint16_t tmp[32];
|
|
|
for(int i=0;i<32;i++)tmp[i]=fillColor;
|
|
|
for(int i=0;i<(h*w);i+=32)
|
|
|
{
|
|
|
LCD->interface->writeGRAM(tmp,32);
|
|
|
}
|
|
|
int rem=(w*h)%32;
|
|
|
if(rem)LCD->interface->writeGRAM(tmp,rem);
|
|
|
if(contSz)
|
|
|
{
|
|
|
ssd2119setFrame(LCD,Xpos,Ypos,w,contSz);
|
|
|
for(int i=0;i<32;i++)tmp[i]=contColor;
|
|
|
rem=(w*contSz)%32;
|
|
|
if(rem)LCD->interface->writeGRAM(tmp,rem);
|
|
|
for(int i=rem;i<(w*contSz);i+=32)
|
|
|
{
|
|
|
LCD->interface->writeGRAM(tmp,32);
|
|
|
}
|
|
|
|
|
|
ssd2119setFrame(LCD,Xpos,Ypos+h-contSz,w,contSz);
|
|
|
rem=(w*contSz)%32;
|
|
|
if(rem)LCD->interface->writeGRAM(tmp,rem);
|
|
|
for(int i=rem;i<(w*contSz);i+=32)
|
|
|
{
|
|
|
LCD->interface->writeGRAM(tmp,32);
|
|
|
}
|
|
|
|
|
|
ssd2119setFrame(LCD,Xpos,Ypos,contSz,h);
|
|
|
rem=(h*contSz)%32;
|
|
|
if(rem)LCD->interface->writeGRAM(tmp,rem);
|
|
|
for(int i=rem;i<(h*contSz);i+=32)
|
|
|
{
|
|
|
LCD->interface->writeGRAM(tmp,32);
|
|
|
}
|
|
|
|
|
|
ssd2119setFrame(LCD,Xpos+w-contSz,Ypos,contSz,h);
|
|
|
rem=(h*contSz)%32;
|
|
|
if(rem)LCD->interface->writeGRAM(tmp,rem);
|
|
|
for(int i=rem;i<(h*contSz);i+=32)
|
|
|
{
|
|
|
LCD->interface->writeGRAM(tmp,32);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void ssd2119paintText(LCD_t* LCD,char* buffer,uint16_t Xpos,uint16_t Ypos,sFONT* font,uint32_t color)
|
|
|
{
|
|
|
int w=font->Width,h=font->Height,bpl=font->bytesPerLine,pix=0,tableoffset=0;
|
|
|
uint16_t tmp[w];
|
|
|
uint16_t linenum=0,charnum=0;
|
|
|
uint8_t line=0;
|
|
|
while(*buffer!='\0')
|
|
|
{
|
|
|
ssd2119setFrame(LCD,Xpos+(charnum*w),Ypos-h,w,1);
|
|
|
LCD->interface->readGRAM(tmp,w);
|
|
|
for(int i=0;i<(h*w);i++)
|
|
|
{
|
|
|
if( ((i%w)==0) ) //read current line to apply text pixmap
|
|
|
{
|
|
|
if(linenum++>0)
|
|
|
{
|
|
|
ssd2119setFrame(LCD,Xpos+(charnum*(w-10)),Ypos + linenum -h,w,1); // TODO remove -10 and generate good fonts!
|
|
|
LCD->interface->writeGRAM(tmp,w);
|
|
|
ssd2119setFrame(LCD,Xpos+(charnum*(w-10)),Ypos + linenum + 1-h,w,1);
|
|
|
LCD->interface->readGRAM(tmp,w);
|
|
|
pix=0;
|
|
|
}
|
|
|
}
|
|
|
if((pix%8) == 0)
|
|
|
{
|
|
|
line=font->table[(((*buffer)-32)*h*bpl)+tableoffset++];
|
|
|
}
|
|
|
if((line & (uint8_t)0x01)==(uint8_t)1)tmp[pix]=(uint16_t)color;
|
|
|
pix++;
|
|
|
line>>=1;
|
|
|
}
|
|
|
linenum=0;
|
|
|
tableoffset=0;
|
|
|
charnum++;
|
|
|
buffer++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
int ssd2119init(struct LCD_t* LCD)
|
|
|
{
|
|
|
if((LCD!=NULL) && (LCD->interface!=NULL) && (LCD->interface->writereg!=NULL))
|
|
|
{
|
|
|
LCD->interface->writereg(0x28,0x0006); // VCOM OTP - Page 55-56 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x00,0x0001); // start Oscillator - Page 36 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x10,0x0000); // Sleep mode - Page 49 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x01,0x72ef); // Driver Output Control - Page 36-39 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x02,0x0600); // LCD Driving Waveform Control - Page 40-42 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x03,0x6a38); // Power Control 1 - Page 43-44 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x11,0x6870); // Entry Mode - Page 50-52 of SSD2119 datasheet
|
|
|
|
|
|
// RAM WRITE DATA MASK
|
|
|
LCD->interface->writereg(0x0f,0x0000); // Gate Scan Position - Page 49 of SSD2119 datasheet
|
|
|
// RAM WRITE DATA MASK
|
|
|
LCD->interface->writereg(0x0b,0x5308); // Frame Cycle Control - Page 45 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x0c,0x0003); // Power Control 2 - Page 47 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x0d,0x000a); // Power Control 3 - Page 48 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x0e,0x2e00); // Power Control 4 - Page 48 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x1e,0x00be); // Power Control 5 - Page 53 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x25,0x8000); // Frame Frequency Control - Page 53 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x26,0x7800); // Analog setting - Page 54 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x4e,0x0000); // Ram Address Set - Page 58 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x4f,0x0000); // Ram Address Set - Page 58 of SSD2119 datasheet
|
|
|
LCD->interface->writereg(0x12,0x08d9); // Sleep mode - Page 49 of SSD2119 datasheet
|
|
|
|
|
|
// -----------------Adjust the Gamma Curve----//
|
|
|
LCD->interface->writereg(0x30,0x0000); //0007
|
|
|
LCD->interface->writereg(0x31,0x0104); //0203
|
|
|
LCD->interface->writereg(0x32,0x0100); //0001
|
|
|
LCD->interface->writereg(0x33,0x0305); //0007
|
|
|
LCD->interface->writereg(0x34,0x0505); //0007
|
|
|
LCD->interface->writereg(0x35,0x0305); //0407
|
|
|
LCD->interface->writereg(0x36,0x0707); //0407
|
|
|
LCD->interface->writereg(0x37,0x0300); //0607
|
|
|
LCD->interface->writereg(0x3a,0x1200); //0106
|
|
|
LCD->interface->writereg(0x3b,0x0800);
|
|
|
LCD->interface->writereg(0x07,0x0033); // Display Control - Page 45 of SSD2119 datasheet
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|