*
*/
+/*
+ * some comments on alpha blending!
+ * ################################
+ *
+ * if c is the result of layer a over layer b with opacity alpha:
+ *
+ * c=alpha*a+(1-alpha)*b and if alpha is a byte (0-255)
+ * => c=alpha*a+(255-alpha)*b
+ *
+ */
+
#include "display.h"
-#include "system.h"
-#include "default_logo.h"
+
+// debug
#include "uart.h"
/*
void display_fill_screen(u8 fill) {
u8 page,width;
+ u8 buf[2];
+
+ buf[0]=0;
+ buf[1]=0;
+
+ switch(fill) {
+ case DISPLAY_FILL_LG:
+ buf[1]=0xff;
+ break;
+ case DISPLAY_FILL_DG:
+ buf[0]=0xff;
+ break;
+ case DISPLAY_FILL_B:
+ buf[0]=0xff;
+ buf[1]=0xff;
+ break;
+ case DISPLAY_FILL_W:
+ default:
+ break;
+ }
for(page=0;page<DISPLAY_PAGE_MAX;page++) {
- DISPLAY_SET_C_ADDR(0);
+ DISPLAY_SET_COL_ADDR(0);
DISPLAY_SET_PAGE_ADDR(page);
for(width=0;width<DISPLAY_DIMX;width++) {
- DISPLAY_DATA=fill;
- DISPLAY_DATA=fill;
+ DISPLAY_DATA=buf[0];
+ DISPLAY_DATA=buf[1];
}
}
}
void display_clear_screen(void) {
- display_fill_screen(0x00);
+ display_fill_screen(DISPLAY_FILL_W);
}
void display_init(void) {
- DISPLAY_EXIT_POWER_SAVE;
-
- DISPLAY_SOFT_RESET;
- pause(0xffffff);
-
+ /* oscillator, regulator, boost, opamp, contrast */
DISPLAY_START_OSCILLATOR;
-
DISPLAY_SET_REGULATOR(7);
-
DISPLAY_SET_CONTRAST(0x38);
-
DISPLAY_SET_CONV_FACTOR(0x01);
-
- DISPLAY_SET_PWM_FRC(0,0);
+ DISPLAY_SET_POWER(DISPLAY_V_BOOST|DISPLAY_REGULATOR|DISPLAY_OPAMP);
// gray scale palette
DISPLAY_SET_WHITE(0,0,0,0);
- DISPLAY_SET_LGRAY(2,2,2,2);
- DISPLAY_SET_DGRAY(6,6,6,6);
+ DISPLAY_SET_LGRAY(5,5,5,5); // obviously 3, but it's too bright!
+ DISPLAY_SET_DGRAY(7,7,7,7); // obviously 6, but again too bright!
DISPLAY_SET_BLACK(9,9,9,9);
- DISPLAY_SET_POWER(DISPLAY_REGULATOR|DISPLAY_OPAMP);
- pause(0xffffff);
- DISPLAY_SET_POWER(DISPLAY_V_BOOST|DISPLAY_REGULATOR|DISPLAY_OPAMP);
-
+ /* normal mode, display depending ram content */
DISPLAY_RAM_CONTENTS_ON;
-
- DISPLAY_NORMAL;
-
display_clear_screen();
+ DISPLAY_NORMAL; // 00 -> white, 11 -> black
+ DISPLAY_SET_COM_ODIR_REMAPPED; // start counting at the top
+ /* switch on the display */
DISPLAY_SET_ON;
}
-void display_load_logo(u8 *src) {
+void display_logo(u8 *src) {
- u8 *s;
u8 page,width;
- s=src;
- if(s==0)
- s=default_logo;
-
for(page=0;page<DISPLAY_PAGE_MAX;page++) {
- DISPLAY_SET_C_ADDR(0);
+ DISPLAY_SET_COL_ADDR(0);
DISPLAY_SET_PAGE_ADDR(page);
for(width=0;width<DISPLAY_DIMX;width++) {
- DISPLAY_DATA=*s++;
- DISPLAY_DATA=*s++;
+ DISPLAY_DATA=*src++;
+ DISPLAY_DATA=*src++;
+ }
+ }
+}
+
+#define display_m2i(m,r) (((((m)[0]>>r)&1)<<1)|(((m)[1]>>r)&1))
+
+void display_draw_rectangle(u8 x,u8 y,u8 w,u8 h,u8 fill,u8 alpha) {
+
+ u8 page,col,row,rmax,cnt;
+ u8 d[2];
+ int ca,cb;
+ u8 a,b,c; // c = a over b
+
+ a=fill&0x03;
+ ca=0;
+ for(cnt=0;cnt<a;cnt++) // contribution of a: alpha*a
+ ca+=alpha;
+
+ for(page=(y>>3);page<=((y+h)>>3);page++) { // page = y/8
+ DISPLAY_SET_PAGE_ADDR(page);
+ rmax=(page+1)<<3; // row max
+ if(rmax>y+h)
+ rmax=y+h;
+ for(col=x;col<x+w;col++) {
+ DISPLAY_SET_COL_ADDR(col);
+ d[0]=DISPLAY_DATA; // dummy read (p.16)
+ d[0]=DISPLAY_DATA;
+ d[1]=DISPLAY_DATA;
+ row=DISPLAY_DATA; // aligne
+ for(row=y;row<rmax;row++) {
+ // contribution of b: (255-alpha)*b
+ b=display_m2i(d,row);
+ cb=0;
+ for(cnt=0;cnt<b;cnt++)
+ cb+=(255-alpha);
+ // finally there is c
+ c=(ca+cb)>>8;
+ d[0]&=~(1<<row);
+ d[1]&=~(1<<row);
+ d[0]|=((c>>1)&1)<<row;
+ d[1]|=(c&1)<<row;
+ }
+ DISPLAY_SET_COL_ADDR(col);
+ DISPLAY_DATA=d[0];
+ DISPLAY_DATA=d[1];
+ }
+ h-=(rmax-y);
+ y=rmax;
+ }
+}
+
+void display_rectangle_page(u8 x,u8 p,u8 w,u8 h,u8 fill,u8 alpha) {
+
+ u8 page,col,row;
+ u8 buf[2];
+ u8 b,c;
+
+ for(page=p;page<p+h;page++) {
+ DISPLAY_SET_PAGE_ADDR(page);
+ for(col=x;col<x+w;col++) {
+ DISPLAY_SET_COL_ADDR(col);
+ buf[0]=DISPLAY_DATA; // dummy read
+ buf[0]=DISPLAY_DATA;
+ buf[1]=DISPLAY_DATA;
+ row=DISPLAY_DATA; // aligne dummy read
+ for(row=0;row<8;row++) {
+ b=display_m2i(buf,row);
+ c=(b*(255-alpha)+fill*alpha)>>8;
+ buf[0]&=~(1<<row);
+ buf[1]&=~(1<<row);
+ if(c&2)
+ buf[0]|=(1<<row);
+ if(c&1)
+ buf[1]|=(1<<row);
+ }
+ DISPLAY_SET_COL_ADDR(col);
+ DISPLAY_DATA=buf[0];
+ DISPLAY_DATA=buf[1];
+ }
+ }
+}
+
+void display_font_page(u8 x,u8 page,u8 *font,u8 fill) {
+
+ /* this only draws page aligned fonts! */
+ u8 cnt,row;
+ u8 c[16];
+
+ /* set the page */
+ DISPLAY_SET_PAGE_ADDR(page);
+
+ /* read old content */
+ DISPLAY_SET_COL_ADDR(x);
+ c[0]=DISPLAY_DATA; // dummy read
+ for(cnt=0;cnt<16;cnt++) {
+ c[cnt++]=DISPLAY_DATA;
+ c[cnt]=DISPLAY_DATA;
+ }
+ cnt=DISPLAY_DATA; // 2 byte aligne dummy read
+
+ /* write new content */
+ DISPLAY_SET_COL_ADDR(x);
+ for(cnt=0;cnt<16;cnt++) {
+ for(row=0;row<8;row++) {
+ if((font[cnt>>1]>>row)&1) {
+ c[cnt]&=~(1<<row);
+ c[cnt+1]&=~(1<<row);
+ c[cnt]|=(((fill>>1)&1)<<row);
+ c[cnt+1]|=((fill&1)<<row);
+ }
+ }
+ DISPLAY_DATA=c[cnt++];
+ DISPLAY_DATA=c[cnt];
+ }
+}
+
+void display_draw_font(u8 x,u8 y,u8 *font,u8 fill,u8 alpha) {
+
+ u8 page,col,row,rmax,cnt,left,cf,rf;
+ u8 d[2];
+ int ca,cb;
+ u8 a,b,c; // c = a over b
+
+ left=8;
+
+ a=fill&0x03;
+ ca=0;
+ for(cnt=0;cnt<a;cnt++) // contribution of a: alpha*a
+ ca+=alpha;
+
+ for(page=(y>>3);page<=((y+8)>>3);page++) { // page = y/8
+ DISPLAY_SET_PAGE_ADDR(page);
+ rmax=(page+1)<<3; // row max
+ if(rmax>y+left)
+ rmax=y+left;
+ cf=0;
+ for(col=x;col<x+8;col++) {
+ DISPLAY_SET_COL_ADDR(col);
+ d[0]=DISPLAY_DATA; // dummy read (p.16)
+ d[0]=DISPLAY_DATA;
+ d[1]=DISPLAY_DATA;
+ rf=0;
+ for(row=y;row<rmax;row++) {
+ // contribution of b: (255-alpha)*b
+ b=display_m2i(d,row);
+ cb=0;
+ for(cnt=0;cnt<b;cnt++)
+ cb+=(255-alpha);
+ // finally there is c
+ if((font[cf]>>row)&1) {
+ c=(ca+cb)>>8;
+ d[0]&=~(1<<row);
+ d[1]&=~(1<<row);
+ d[0]|=((c>>1)&1)<<row;
+ d[1]|=(c&1)<<row;
+ }
+ rf+=1;
+ }
+ DISPLAY_SET_COL_ADDR(col);
+ DISPLAY_DATA=d[0];
+ DISPLAY_DATA=d[1];
+ cf+=1;
}
+ left-=(rmax-y);
+ y=rmax;
}
}