|
Forum Index : Microcontroller and PC projects : CPLD TFT
| Author | Message | ||||
| lew247 Guru Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
Will there be support for CPLD TFT LCD's? Or is it possible to add support using a CFunction or something else? They are superior to the SDD1963 and have 8 page memory on them They "look" to have a similar pinout. [quote] 7 inch TFT LCD Display Module Using CPLD + SDRAM drive RGB interface display(far more superior than SSD1963 and RA8875) 8080 timing 16-bit parallel bus interface Resolution 800 x 480 16M color display Integrated 8 memory (can be used as extended memory when rest) Background write data No need to initialize Support 51, AVR, STM32 and other types SCM drive directly Provides a series of practical features when convert between bus and RGB interface Interface Definition: GND: Ground 3.3V: Positive power supply 3.3V NC: Empty RS: data / command switch WR: Write Data Clock RD: Read Data Clock DB8-DB15: Upper 8-Bit Data Bus CS: Chip Select F_CS: FLASH Chip Select (module aside FLASH chip W25X16, default is not affixed to pieces, do reserve purposes) REST: Reset (reset operation procedure: pull low, sustained 8ms; then pull high, sustained 8ms) 5V: backlight power supply 5V input LED_A: backlight control (factory default backlight is controlled by program,0-16 Adjustable backlight brightness, without LED_A control, if required by the LED_A manual control on the module Backlight Control Department to modify resistor pad jumpers can be changed manually LED_A control, manual control when, LED_A access high-back light, then lower the backlight off, the PWM signal is adjustable brightness) DB0-DB7: Lower 8-bit data bus Touch controller (XPT2046) interface: T_CLK: Clock T_CS: Chip Select T_DIN: Data Entry (ie MOSI) T_DO: Data Out (ie MISO) T_IRQ: Data Interrupt (usually high, touch low) SD card interface: SD_DO: MISO SD_CLK: Clock SD_DIN: MOSI SD_CS: Chip Select [/quote] |
||||
| lew247 Guru Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
Found a video of the LCD working it loads full page pictures practically instantly Video HERE The one shown is programmed in Bascom |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10570 |
No it doesn't. It switches between pre-loaded images on specific pages very quickly. Loading is dependent on the SD card speed (or wherever else the pics come from). The unit uses a 16-bit bus which isn't ideal with the Micromite as there isn't a a 16-bit port which doesn't conflict with various critical special function pins (the one thing I disagree with Geoff about in the way he allocated pins on the MM+). So the display won't be very easy to drive very fast. Also, note that it appears to be only RGB565 whereas the SSD1963 is RGB888. The display is very nice and a loadable driver is not too difficult but it is too expensive for just playing. Also note that the GUI controls on the MM+ wouldn't work across multiple pages as there is no way of telling them which page they are on. |
||||
| lew247 Guru Joined: 23/12/2015 Location: United KingdomPosts: 1702 |
That's a shame, I thought it might use the same pinout as the SSD1963, they look almost identical. It would have been great if it had been possible. |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
I know this is an old topic, but I am new here I would like to use my existing 7" CPLD display with my latest acquisition Micromite Extreme MMX144, which means writing a driver. Since I am totally New to MMBasic I have no idea where to start. I understand the initialisation is very simple unlike the SSD1963. Are the CFunctions like Write_Cmd, Write_Data, and Write_Com_Data for 16 bit available to MMBasic users? If so how do I call them? |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10570 |
Best place is to write a user driver in Basic see the file "User Display Driver.txt" in the Micromite distribution from Geoff and this thread . Once this is working you can then port to C. Best start for that is to use one of my drivers as a template. I've attached a recent driver you can use as a template. It is SPI rather than parallel but this is just a matter of changing the HW I/F code 2018-04-06_224001_ILI9481Loadable.X.zip |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
Thanks for your reply, I have got the display working of sorts, but only in basic which is as expected very slow. I don't have the skills to write my own CFuntions to speed it up as don't understand everything that is going on in your example. I enclose my limited efforts at coding part of a basic driver which all work. ' testing driver for TFT 16bit CPLD Controller setpin 139, dout 'reset setpin 140, dout 'RS setpin 141, dout 'WR setpin 142, dout 'RD setpin 143, dout 'CS setpin 114, dout 'VL D0 on port J setpin 115, dout setpin 116, dout setpin 117, dout setpin 131, dout setpin 132, dout setpin 133, dout setpin 134, dout ' D7 on port J setpin 7, dout 'VH D8 on port J setpin 8, dout setpin 10, dout setpin 27, dout setpin 9, dout setpin 28, dout setpin 29, dout setpin 30, dout ' D15 on port j pin(139) = 1 pin(140) = 1 pin(141) = 1 pin(142) = 1 pin(143) = 1 ' Program start print "Start" CPLD_Init draw_FRectangle(0,0,360,260,&hc6F0) 'Clear a patch 'lcd_clear(&hffff) 'Clear to white draw_FRectangle(80,80,350,250,&h001F) 'clear blue patch draw_Rectangle(80,80,350,250,&hf800) 'draw_HLine(80,80,350,&hF800) draw_FRectangle(150,100,300,200,&h07c0) 'draw box filled green draw_Rectangle(150,100,300,200,&hf6f0) draw_HLine(10,10,100,&h0000) draw_VLine(10,10,100,&h0000) draw_Rectangle(20,20,120,120,&hf800) set_Pixel(100,100,&hffff) ' End of program so far sub lcd_Writ_Bus(reg%) port(114,4,131,4,7,2,10,1,27,1,9,1,28,3) = reg% pin(141) = 0 'WR low pin(141) = 1 'WR high end sub sub lcd_WR_DATA(da%) pin(140) = 1 lcd_Writ_Bus(da%) end sub sub lcd_WR_REG(da%) pin(140) = 0 'RS low lcd_Writ_Bus(da%) end sub sub Address_set(x1%,y1%,x2%,y2%) lcd_WR_REG(&h0002) lcd_WR_DATA(y1%) lcd_WR_REG(&h0003) lcd_WR_DATA(x1%) lcd_WR_REG(&h0006) lcd_WR_DATA(y2%) lcd_WR_REG(&h0007) lcd_WR_DATA(x2%) lcd_WR_REG(&h000F) end sub sub CPLD_Init pin(139) = 0 'Reset low pause 1 pin(139) = 1 'Reset high pause 1 pin(143) = 0 'CS low lcd_WR_REG(&h0001) lcd_WR_DATA(&h000F) pin(143) = 1 'CS low print "Reset TFT" end sub sub lcd_Clear(Col%) 'clear screen Address_set(0,0,799,479) for i% = 0 to 799 for j% = 0 to 479 lcd_WR_DATA(Col%) next j% next i% end sub sub set_Pixel(x1,y1,col%) Address_set(x1,y1,x1,y1) lcd_WR_DATA(col%) end sub sub draw_HLine(x1,y1,x2,Col%) Address_set(x1,y1,x2,y1) for i% = x1 to x2 lcd_WR_DATA(Col%) next i% end sub sub draw_VLine(x1,y1,y2,Col%) Address_set(x1,y1,x1,y2) for j% = y1 to y2 lcd_WR_DATA(Col%) next j% end sub sub draw_Rectangle(x1,y1,x2,y2,Col%) Address_set(x1,y1,x2,y2) draw_HLine(x1,y1,x2,Col%) draw_HLine(x1,y2,x2,Col%) draw_VLine(x1,y1,y2,Col%) draw_VLine(x2,y1,y2,Col%) end sub sub draw_FRectangle(x1,y1,x2,y2,Col%) 'filled rectangle Address_set(x1,y1,x2,y2) for i% = x1 to x2 for j% = y1 to y2 lcd_WR_DATA(Col%) next j% next i% end sub |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
Off topic but how do you put the CODE in a nice white box??? |
||||
palcal![]() Guru Joined: 12/10/2011 Location: AustraliaPosts: 2006 |
At the top of the post reply page you will see a box marked 'Code' click on it and paste your code in the middle between the two sets of brackets. Paul "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
I have tried using my CPLD initialisation code with OPTION LCDPANEL USER, 800,480 setting as described in writing display drivers in basic, it semms to partially work. CLS does not work and box and line only seem to work on black and white, is this normal? |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
One for matherp I think. I have finally got my CPLD driver working as a CFunction. All LCD drawing functions work including Text command including scale of font in the Text command, the gui commands seem to work OK if the Font command is set to 1. If I set Font 2 or higher it just clears the space where the command used would write to the screen. Is there a special way the Font command hooks into the TFT drawing routines. As expected everything works OK on a SSD1963 display with appropriate options set. I have used the SSD1963_44 16 bit source with mods to achieve this. Trevor |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
Following my previous post, here is the CFunction I have been working on to get my CPLD display working with a modified MM E100. TREVOR /******************************************************************************* * * Driver for CPLD Display written as CFunctions * * (c) Peter Mather 2015 with acknowledgements to Peter Carnegie & Geoff Graham * was SSD1963_44 modified by Trevor Henshaw 21/May/2018 * * This CFunction MUST be compiled with Optimization Level 1, -O1 * -O2,-O3,-Os will compile successfully, but generate exceptions at runtime. * * When Generating the CFunction, use MERGE CFunction mode, and name the CFunction * CPLDinit * * Entry point is function long long main(long long *MyAddress, * long long *RST, * long long *orientation * long long *size) * * V1.0 2015-07-21 Peter Mather * 1.01 Change orientation codes to 1:landscape, 2:portrait, 3:rlandscape, 4:rportrait * 1.02 Use fixed PortC pinout for maximum performance * 1.03 Stripped routines for use as loadable LIBRARY * 1.04 Conditional compilation for 44 and 64-pin parts * 1.1 Convert to Nathan approach * 1.11 Minor change for compatibility with touch and restricting page usage * 1.2 Implement RGB565, add-in triangle drawing read/write ******************************************************************************/ #define Version 111 //Version 1.11 #include <stdarg.h> #include <xc.h> // Required for SFR defs #include <sys/attribs.h> // Required to use __longramfunc__ #include "CFunctions.h" #define MX470 //Comment out for compilation for 44-pin part #define pin100 #define RGB565 #define aport *(volatile unsigned int *)(0xbf886030) //latch registers #define aclrport *(volatile unsigned int *)(0xbf886034) //latch registers #define asetport *(volatile unsigned int *)(0xbf886038) //latch registers #define aread *(volatile unsigned int *)(0xbf886020) //latch registers #define atrisinv *(volatile unsigned int *)(0xbf88601C) //latch registers #define bclrport *(volatile unsigned int *)(0xbf886134) //latch registers #define bsetport *(volatile unsigned int *)(0xbf886138) //latch registers #define cport *(volatile unsigned int *)(0xbf886230) //latch registers #define cread *(volatile unsigned int *)(0xbf886220) //latch registers #define ctrisinv *(volatile unsigned int *)(0xbf88621C) //latch registers #define cclrport *(volatile unsigned int *)(0xbf886234) //latch registers #define csetport *(volatile unsigned int *)(0xbf886238) //latch registers #define eport *(volatile unsigned int *)(0xbf886430) //latch registers #define eread *(volatile unsigned int *)(0xbf886420) //latch registers #define etrisinv *(volatile unsigned int *)(0xbf88641C) //latch registers #define eclrport *(volatile unsigned int *)(0xbf886434) //latch registers #define esetport *(volatile unsigned int *)(0xbf886438) //latch registers #define DEVID (*(volatile unsigned int *)0xBF80F220) #define swap(a, b) {int t; t = a; a = b; b = t; } //Offsets into the persistent RAM of variables #ifdef MX470 #ifndef pin100 #define RS_Pin_No 27 #define WR_Pin_No 24 #define RS_Pin 0x1000 #define WR_Pin 0x0800 #define clrport bclrport #define setport bsetport #else #define RS_Pin_No 18 #define WR_Pin_No 19 #define RS_Pin 0x100 #define WR_Pin 0x200 #define RD_Pin_No 6 #define clrport eclrport #define setport esetport #endif #define port eport // Data port Db0-Db7 #define portH aport // Data port Db8-Db15 #define read eread #define trisinv etrisinv #define RSLo PinSetBit(RS_Pin_No,LATCLR); #define RSHi PinSetBit(RS_Pin_No,LATSET); #define WRLo {PinSetBit(WR_Pin_No,LATCLR);asm("NOP");} #define WRHi {PinSetBit(WR_Pin_No,LATSET);asm("NOP");} #else #define RS_Pin_No 4 #define WR_Pin_No 5 #define RS_Pin 0x100 #define WR_Pin 0x200 #define clrport cclrport #define setport csetport #define port cport #define read cread #define trisinv ctrisinv #define RSLo clrport=RS_Pin #define RSHi setport=RS_Pin #define WRLo clrport=WR_Pin #define WRHi setport=WR_Pin #endif #define Both WR_Pin | RS_Pin #define RDLo (*(volatile unsigned int *)RDclrport)=RDpin #define RDHi (*(volatile unsigned int *)RDsetport)=RDpin #define LANDSCAPE 1 #define PORTRAIT 2 #define RLANDSCAPE 3 #define RPORTRAIT 4 /************************************************************************* * * defines start/end coordinates for memory access from host to SSD1963 * also maps the start and end points to suit the orientation * * This function is a modified version of the function inside the MMBasic * Interpreter for MM+ on 'MX470 chips * * **************************************************************************/ void defineregion(long x, long y, long width,long height){ //Address Set long x1=x,x2=x+width-1,y1=y,y2=y+height-1; unsigned long xstart,xend,ystart,yend,Vertical,Horizontal; RSLo; if(HRes>VRes){ Vertical=VRes; Horizontal=HRes; } else { Vertical=HRes; Horizontal=VRes; } if(Option->DISPLAY_ORIENTATION!=LANDSCAPE)goto isP; xstart = x1; xend = x2; ystart = y1; yend = y2 ; //Must be Landscape goto setreg; isP: if(Option->DISPLAY_ORIENTATION!=PORTRAIT)goto isRL; xstart = y1; xend = y2; ystart = (Vertical - 1) - x2; yend = (Vertical - 1) - x1; goto setreg; isRL: if(Option->DISPLAY_ORIENTATION!=RLANDSCAPE)goto isRP; xstart = (Horizontal - 1) - x2; xend = (Horizontal - 1) - x1; ystart = (Vertical - 1) - y2; yend = (Vertical - 1) - y1; goto setreg; isRP: xstart = (Horizontal - 1) - y2; xend = (Horizontal - 1) - y1; ystart = x1; yend = x2; setreg: // Address Set these are the registers used for setting screen work area port=0x02; RSLo; WRLo; WRHi; // RS low portH=(ystart>>8 ); RSHi; port=(ystart & 0x00FF) | Both; WRLo; WRHi; // RS HIGH port=0x03; RSLo; WRLo; WRHi; // RS low portH=(xstart>>8 ); RSHi; port=(xstart & 0x00FF) | Both; WRLo; WRHi; // RS HIGH port=0x06; RSLo; WRLo; WRHi; // RS low portH=(yend>>8 ); RSHi; port=(yend & 0x00FF) | Both; WRLo; WRHi; // RS HIGH RSHi; port=0x07; RSLo; WRLo; WRHi; // RS low portH=(xend>>8 ); RSHi; port=(xend & 0x00FF) | Both; WRLo; WRHi; // RS HIGH*/ port=0x0F; RSLo; WRLo; WRHi; // RS low } void DisplayPage(int pg){ // NOT implemented if(pg > 7) {pg = 0;} port=0x04; RSLo; WRLo; WRHi; // RS low port=(pg & 0x00FF) | Both; RSHi; WRLo; WRHi; // RS HIGH*/ } void WritePage(int pg){ // Not implemented if(pg > 7) {pg = 0;} port=0x05; RSLo; WRLo; WRHi; // RS low port=(pg & 0x00FF) | Both; RSHi; WRLo; WRHi; // RS HIGH*/ } /*********************************************************************************************** * Display the bitmap of a char on the TFT panel * * This function is NEVER called by MMBasic programs * * This is optimised for the * x, y - the top left of the char * width, height - size of the char's bitmap * scale - how much to scale the bitmap * fg, bg - foreground and background colour * bitmap - pointer to the butmap * * This function is a modified version of the function inside the MMBasic Interpreter * for MM+ on 'MX470 chips ***********************************************************************************************/ void DrawBitmap_CPLD(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap ){ long i, j, k, m, n; unsigned int fhb, flb, bhb, blb, xtest, ytest; unsigned char *p; xtest=HRes; ytest=VRes; fhb = ((fc >> 16) & 0b11111000) | ((fc >> 13) & 0b00000111); flb = ((fc >> 5) & 0b11100000) | ((fc >> 3) & 0b00011111); bhb = ((bc >> 16) & 0b11111000) | ((bc >> 13) & 0b00000111); blb = ((bc >> 5) & 0b11100000) | ((bc >> 3) & 0b00011111); n=0; defineregion(x1,y1,width*scale,height*scale); RSHi; for(i = 0; i < height; i++) { // step thru the font scan line by line for(j = 0; j < scale; j++) { // repeat lines to scale the font for(k = 0; k < width; k++) { // step through each bit in a scan line for(m = 0; m < scale; m++) { // repeat pixels to scale in the x axis if(x1 + k * scale + m >= 0 && x1 + k * scale + m < xtest && y1 + i * scale + j >= 0 && y1 + i * scale + j < ytest) { // if the coordinates are valid if((bitmap[((i * width) + k)/8] >> (((height * width) - ((i * width) + k) - 1) %8)) & 1) { portH = fhb; port = (flb & 0xFF) | Both; WRLo; WRHi; } else { // if(bc==1 && Option->LCD_CS!=0){ portH = bhb; port = (blb & 0xFF) | Both; WRLo; WRHi; n+=2; // } } } } } } } // } if(bc==1 && Option->LCD_CS!=0) FreeMemory(p); } /****************************************************************** * * Called by MMBasic Interpreter to draw a rectangle * on the CPLD panel * * This function is NEVER called by MMBasic programs * * *****************************************************************/ void DrawRectangle_CPLD(int x1, int y1, int x2, int y2, int fc){ int t,j; long width, height; unsigned long i,ch,cl; // make sure the coordinates are kept within the display area if(x2 <= x1) { t = x1; x1 = x2; x2 = t; } if(y2 <= y1) { t = y1; y1 = y2; y2 = t; } if(x1 < 0) x1 = 0; if(x1 >= HRes) x1 = HRes - 1; if(x2 < 0) x2 = 0; if(x2 >= HRes) x2 = HRes - 1; if(y1 < 0) y1 = 0; if(y1 >= VRes) y1 = VRes - 1; if(y2 < 0) y2 = 0; if(y2 >= VRes) y2 = VRes - 1; width=x2-x1+1; height=y2-y1+1; i=width*height; //Convert fc to RGB565 ch = ((fc >> 16) & 0b11111000) | ((fc >> 13) & 0b00000111); cl = ((fc >> 5) & 0b11100000) | ((fc >> 3) & 0b00011111); //ch = (((fc>>19)&0x1F)<<11)|(((fc>>10)&0x3F)<<6)|(((fc>>3)&0x1F)); defineregion(x1,y1,width,height); RSHi; for(i = 0; i < width; i++){ for(j = 0; j < height; j++){ portH = ch; port = (cl & 0x00FF) | Both; WRLo; WRHi; } } } int ReadRectangle(int x1, int y1, int width, int height, int pos, char *p ){ int j,RDpin, RDsetport, RDclrport; RDpin=1<<GetPinBit(Option->LCD_CS); RDsetport=(unsigned int)GetPortAddr(Option->LCD_CS,LATSET); RDclrport=(unsigned int)GetPortAddr(Option->LCD_CS,LATCLR); #ifdef RGB565 j=width*height*2+pos; #else j=width*height*3+pos; #endif defineregion(x1,y1,width,height); #ifdef MX470 #ifndef pin100 RSLo; #endif #endif port=0x22E ; WRLo; WRHi; // RS low #ifdef MX470 #ifndef pin100 RSHi; #endif #endif trisinv=0xFF; //set pins to read #ifdef RGB565 atrisinv=0xFF; #endif do { //read in the screen area to be overlayed #ifndef RGB565 RDLo; asm("NOP");asm("NOP");asm("NOP"); RDHi; p[pos++]=(read & 0xFF); RDLo; asm("NOP");asm("NOP");asm("NOP"); RDHi; p[pos++]=(read & 0xFF); RDLo; asm("NOP");asm("NOP");asm("NOP"); RDHi; p[pos++]=(read & 0xFF); #else RDLo; asm("NOP");asm("NOP");asm("NOP"); RDHi; p[pos++]=(read & 0xFF); p[pos++]=(aread & 0xFF); #endif } while(pos<j); trisinv=0xFF; //set pins to write #ifdef RGB565 atrisinv=0xFF; #endif } int RestoreRectangle(int x1, int y1, int width, int height, int pos, char p[]){ int i; defineregion(x1,y1,width,height); i=width*height; #ifdef MX470 #ifndef pin100 RSLo; #endif #endif #ifdef RGB565 aclrport=0xFF; #endif port=0x22C ; WRLo; WRHi; // RS low #ifdef MX470 #ifndef pin100 RSHi; #endif #endif #ifdef RGB565 while (i--) { port=p[pos++] | Both; asetport=p[pos]; aclrport=(p[pos++]^0xFF); WRLo; WRHi; } #else while(i--){ port=p[pos++] | Both; WRLo; WRHi; port=p[pos++] | Both; WRLo; WRHi; port=p[pos++] | Both; WRLo; WRHi; } #endif return pos; } long triangles(int mode, int buffpos, char *buff, long col, long x0, long y0, long x1, long y1,long x2, long y2) {//Cfunction long a, b, y, last; long dx01, dy01, dx02, dy02, dx12, dy12, sa, sb; if (y0>y1) { swap(y0, y1); swap(x0, x1); } if (y1>y2) { swap(y2, y1); swap(x2, x1); } if (y0>y1) { swap(y0, y1); swap(x0, x1); } if(y0==y2) { // Handle awkward all-on-same-line case as its own thing a=x0; b=x0; if(x1<a) { a=x1; } else { if(x1>b) b=x1; } if(x2<a) { a=x2; } else { if(x2>b) b=x2; } if(mode==0){ buffpos=ReadRectangle(a,y0,1,b-a+1,buffpos,buff); } else if(mode==1) { buffpos=RestoreRectangle(a,y0,1,b-a+1,buffpos,buff); } else { DrawRectangle_CPLD(a,y0,a,b-a+y0,col); } } else { dx01=x1-x0; dy01=y1-y0; dx02=x2-x0; dy02=y2-y0; dx12=x2-x1; dy12=y2-y1; sa=0; sb=0; if(y1==y2) { last=y1; //Include y1 scanline } else { last=y1-1; // Skip it } for (y=y0;y<=last;y++){ a=x0+sa / dy01; b=x0+sb / dy02; sa=sa+dx01; sb=sb+dx02; a=x0+(x1-x0) * (y-y0) / (y1-y0); b=x0+(x2-x0) * (y-y0) / (y2-y0); if(a>b)swap(a,b); if(mode==0){ buffpos=ReadRectangle(a,y,b-a+1,1,buffpos,buff); } else if(mode==1) { buffpos=RestoreRectangle(a,y,b-a+1,1,buffpos,buff); } else { DrawRectangle_CPLD(a,y,b,y,col); } } sa=dx12 * (y-y1); sb=dx02 * (y-y0); while (y<=y2){ a=x1+sa / dy12; b=x0+sb / dy02; sa=sa+dx12; sb=sb+dx02; a=x1+(x2-x1) * (y-y1) / (y2-y1); b=x0+(x2-x0) * (y-y0) / (y2-y0); if(a>b) swap(a,b); if(mode==0){ buffpos=ReadRectangle(a,y,b-a+1,1,buffpos,buff); } else if(mode==1) { buffpos=RestoreRectangle(a,y,b-a+1,1,buffpos,buff); } else { DrawRectangle_CPLD(a,y,b,y,col); } y=y+1; } } return buffpos; } __attribute__((noinline)) void getFPC(void *a, void *b, volatile unsigned int *c) { *c = (unsigned int) (__builtin_return_address (0) - (b -a)) ; } void pstring(const char *s){ volatile unsigned int libAddr ; getFPC(NULL,&&getFPCLab,&libAddr) ; // warning can be ignored, stupid editor getFPCLab: { } unsigned char * testData = (unsigned char *)((void *)s + libAddr ); MMPrintString(testData); } /******************************************************************************* * * CPLDinit : Initialise the CFunction Driver Sub-System * * Function called to initialise the driver SubSystem * * CPLDinit is ALWAYS called from an MMBasic program * On exit, vectors DrawRectangleVector, and DrawBitmapVector will * be set to point to the CFunctions DrawRectangle_SSD1963 and * DrawBitmap_SSD1963 respectively * * Input Arguments * MyAddress: The Address of the CFunction, use PEEK(CFUNADDR CPLDinit) * RST: The pin connected to the Reset input on the display * orientation: * is 0 for Portrait orientation, 1 for reverse portrait, 2 for landscape, 3 for reverse landscape * size: The display size 4, 5, or 7" * * Exit Value Version * * Note, For added performance, it may be desirable to create a * separate WriteData function which doen't asser/de-asser CS for each byte and * instead use block CSLo/CSHi around data transfers. These "block" CSLo/CSHi * statements have been left in the code as comments. * ******************************************************************************/ //CFunction CPLDinit long long main(char *orientation, unsigned char *p1, long long p2[], long long p3[], long long p4[], long long p5[], long long p6[],long long p7[], long long p8[]){ int t,HorizontalRes,VerticalRes; unsigned int p[17]; int i,j,c; if(Option->LCD_CS){ PinSetBit(Option->LCD_CS, LATSET); } volatile unsigned int libAddr ; getFPC(NULL,&&getFPCLab,&libAddr) ; // warning can be ignored, stupid editor getFPCLab: { } if(*orientation>=0 && *orientation<=4){ Option->DISPLAY_ORIENTATION=*orientation; Option->LCD_CS=0; #ifndef MX470 if(p2[0])Option->LCD_CS=p2[0]; #else if(*p1)Option->LCD_CS=*p1; #endif Option->DISPLAY_ORIENTATION=*orientation; Option->LCD_CD=*p2; //save the display size as the display type for use in the driver routines #ifdef MX470 #ifndef pin100 Option->LCD_Reset=28; p[0]=60; p[1]=61; p[2]=62; p[3]=63; p[4]=64; p[5]=1; p[6]=2; p[7]=3; #else Option->LCD_Reset=42; p[0]=93; p[1]=94; p[2]=98; p[3]=99; p[4]=100; p[5]=3; p[6]=4; p[7]=5; p[8]=17; p[9]=38; p[10]=58; p[11]=59; p[12]=60; p[13]=61; p[14]=91; p[15]=92; p[16]=48; #endif #else Option->LCD_Reset=*p1; p[0]=25; p[1]=26; p[2]=27; p[3]=36; p[4]=37; p[5]=38; p[6]=2; p[7]=3; #endif for(j=0;j<17;j++){ ExtCfg(p[j],EXT_DIG_OUT,0);ExtCfg(p[j],EXT_BOOT_RESERVED,0); PinSetBit(p[j],LATCLR); } //Control Signals ExtCfg(RS_Pin_No,EXT_DIG_OUT,0);ExtCfg(RS_Pin_No,EXT_BOOT_RESERVED,0); RSHi; ExtCfg(WR_Pin_No,EXT_DIG_OUT,0);ExtCfg(WR_Pin_No,EXT_BOOT_RESERVED,0); WRHi; ExtCfg(Option->LCD_Reset,EXT_DIG_OUT,0);ExtCfg(Option->LCD_Reset,EXT_BOOT_RESERVED,0); PinSetBit(Option->LCD_Reset, LATSET); if(Option->LCD_CS){ ExtCfg(Option->LCD_CS, EXT_DIG_OUT,0); ExtCfg(Option->LCD_CS, EXT_BOOT_RESERVED,0); PinSetBit(Option->LCD_CS, LATSET); } //Save DisplayMetrics if(Option->LCD_CD<5){ HorizontalRes=480; // if(Option->DISPLAY_ORIENTATION==1) VerticalRes=272*3; //3 frame buffers /*else*/ VerticalRes=272; } else { HorizontalRes=800; VerticalRes=480; HRes = 800; VRes = 480; } //Reset the CPLD PinSetBit(Option->LCD_Reset,LATSET); uSec(10000); PinSetBit(Option->LCD_Reset,LATCLR); uSec(10000); PinSetBit(Option->LCD_Reset,LATSET); uSec(10000); port=0x0F; RSLo; WRLo; WRHi; // RS low port=0x01; RSLo; WRLo; WRHi; // RS low port=0x10; RSHi; // RS high portH=0x00 | Both; WRLo; WRHi; // RS high port=0x0F; RSLo; WRLo; WRHi;// RS low PinSetBit(p[16],LATSET); //Turn on backlight if(Option->DISPLAY_ORIENTATION&1){ HRes=HorizontalRes; VRes=VerticalRes; } else { VRes=HorizontalRes; HRes=VerticalRes; } //Save the current values of the Vectors //Set the DrawRectangle vector to point to our function DrawRectangleVector= (unsigned int)&DrawRectangle_CPLD + libAddr; //Set the DrawBitmap vector to point to our function DrawBitmapVector=(unsigned int)&DrawBitmap_CPLD + libAddr; // DisplayPageVector=(unsigned int)&DisplayPage +libAddr; // WritePageVector=(unsigned int)&WritePage +libAddr; //Clear Screen to Black if(Option->LCD_CD<5) { DrawRectangle(0,0,HRes-1,VRes*3-1,0x000000); } else { DrawRectangle(0,0,HRes-1,VRes-1,0x000000); } #ifdef MX470 #ifndef pin100 static const char startup[]="SSD1963_64 driver loaded\r\n"; #else static const char startup[]="CPLD_100 driver loaded\r\n"; #endif #else static const char startup[]="SSD1963_44 driver loaded\r\n"; #endif pstring(startup); } } // . EVERYTHING BELOW COMMENTED OUT /* else if(*orientation==5){ int num=p1[0],a=1; unsigned char ch,cm; if(p2!=NULL){ num=*p2-1; a=0; } #ifdef RGB565 while (a<num) { // port=p1[a++] | Both; asetport=p1[a]; aclrport=(p1[a++]^0xFF); ch=p1[a++] & 0b11111000; ch|=p1[a]>>5; cm=(p1[a++]<<3) & 0b11100000; cm|=(p1[a++]>>3); port=cm | Both; asetport=ch; aclrport=(ch^0xFF); WRLo; WRHi; } #else while(a<num){ port=p1[a++] | Both; WRLo; WRHi; port=p1[a++] | Both; WRLo; WRHi; port=p1[a++] | Both; WRLo; WRHi; } #endif } else if(*orientation==6){ return ReadRectangle(*p2, *p3, *p4, *p5, *p6, p1 ); } else if(*orientation==7){ return RestoreRectangle(p2[0], p3[0], p4[0], p5[0], p6[0], p1 ); } else if(*orientation==8){ defineregion(*p1, *p2, *p3, *p4); #ifdef MX470 #ifndef pin100 RSLo; #endif #endif #ifdef RGB565 aclrport=0xFF; #endif port=0x22C ; WRLo; WRHi; // RS low #ifdef MX470 #ifndef pin100 RSHi; #endif #endif return 8; } else if(*orientation==9){ if(Option->DISPLAY_ORIENTATION==1){ VRes=272*3; j=(*p1-1) * 272; write_command_data(0x37,2,j>>8,j&0xFF); } } #ifdef RGB565 else if(*orientation==10){ int num=p1[0],a=1,astore; astore=aport & 0xFF00; if(p2!=NULL){ num=*p2-1; a=0; } while (a<num) { aport=p1[a++]|astore; port=p1[a++] | Both; WRLo; WRHi; } #endif } else { //must be triangles int count=*orientation & 0x7F; int i=0,j,buffpos=0; while(i<count && p2<0){ //repeat for any restores buffpos=triangles(1,buffpos,p1,p2,p3,p4,p5,p6,p7,p8); i++; } buffpos=0; j=i; while(i<count && p2>=0){ //repeat for any store and write commands buffpos=triangles(0,buffpos,p1,p2,p3,p4,p5,p6,p7,p8); i++; } i=j; while(i<count && p2>=0){ //repeat for any store and write commands buffpos=triangles(2,buffpos,p1,p2,p3,p4,p5,p6,p7,p8); i++; } return buffpos>>3; }*/ //} |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10570 |
No: do different fonts work with the TEXT command? Please confirm the connections you are using on the E100 |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
Hi Peter, Just to be clear I am using a spare E100 board wired up for 16 bit. The low data port is PortE, pins 93,94,98,99,100,3,4,5 that is Db0-7 High data port is PortA, pins 17,38,58,59,60,61,91,92 that is Db8-15 RS pin 18, WR pin 19, RD pin 6, 42 pin reset and 48 LedA. CS is permanently grounded. I haven't tested every command, but basic graphics routines seem to work as expected. When I tried the Pump example screen it all went wrong, setting the GUI font to greater than 1 was the main cause. I haven't tried running that demo on the SSD1963_44 to see if there is same problem with the loadable.(will try that next). Trevor |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
I have just tried seven segment and dot matrix fonts as given in firmware pack with the Text command and they work ok even when scaled up. Trevor |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
I have now tried the Pump graphics screen example on the SSD1963_44 loadable driver and it works OK. Using my CPLD screen and the modified driver works with the Pump example if I change all the FONT commands to "FONT 1,2" instead of "FONT 2" & "FONT 3". It does seem that no-one else is interested in what is going on here, maybe these screens are not much liked by this group, but they are fully supported in the Arduino world. I am trying to move on from that! Trevor |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
One for matherp again, I wish to setup a couple of calls to the CPLD driver, one to switch ram pages to write to and one to switch ram pages to display. These calls need to be called from Basic. The question is how do I create 2 routines to call from basic that give me access to protected ports and control pins within the driver and how do I call them. I suspect it is not that difficult but I don't know where to start. PS any thoughts on the Font thing? Trevor |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10570 |
These need to be called from the same routine that sets up the driver. See the SSD1963 driver for how I have done it (code you have commented out). Sorry - no idea. If different fonts are working using the "TEXT" command then the driver is working. The GUI commands call the same driver routines. |
||||
| TrevorH Senior Member Joined: 06/04/2018 Location: United KingdomPosts: 145 |
@matherp Got it sorted! paged ram switching now working, by adding 2 parameters to the front of the queue, one for display page and one for write page. But, there always is a But, how do I trap if I miss one of the parameters. If I do, I get an exception and processor restart and CFunction reload. If I miss both I get syntax error. On the Font thing, after looking at Geoff's source code I thought the GUI routines call "SpecialDraw..." routines that seems to built in, but I am guessing ????. Trevor. |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10570 |
See tutorial 4 for how to implement error handling in a CFunction. Then you need to check for parameters missing. I think (but not sure) you need to fully specify the CFunction call with the parameter list in Basic e.g. CFunction SGetStr(float, integer, integer) string and then Basic will generate NULL parameters to the Cfunction for missing parameters void myfunc(int *fred, int *bert){ if(bert==NULL).... } but you will need to test this. Yes: but these all resolve into calls to DrawBitamp or Drawrectangle |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |