1.8" color LCD (TFT)- any PIC code around?

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
Excellent! Good work finding that fault out.

I've been caught myself with similar issues when translating my old code from PIC 16F to new 18F chips and casually replacing "PORTB" with "LATB" etc.

That is another good reason to keep C code vertical with one process on each line, separating tests and writes so things like;
if(PORTB.F0)
{
LATB.F0 = 1;
}
will be easier to update and translate than when people do things like;
if(PORTB.F0=1)
where they perform a write to a port or a variable inside a test.
Using C as such has caused a big advance for me, if you consider assembler source like this:

Rich (BB code):
l_push:
 lfsr d'1',v_stackptr
 movff INDF1,FSR1L
 decf INDF1,f,ACCESS
 movwf INDF1,ACCESS
 return

l_pop:
 lfsr d'1',v_stackptr
 movff INDF1,FSR1L
 incf INDF1,f,ACCESS
 movf INDF1,w,ACCESS
 return
  
 org 0x0100
l_refresh:
 bcf INTCON,TMR0IF,ACCESS 
 
 incf v_tmr0_ctr,f
 btfss v_tmr0_ctr,d'4'
 goto l_refresh_skip0
 
 call l_refresh_load   
 call l_refresh_store
 clrf v_tmr0_ctr
 
l_refresh_skip0:
 incf v_ledctr_0,f
 btfss v_ledctr_0,d'6'
 goto l_refresh_skip1
 
 btfsc v_ledctr_1,d'3'
 goto l_led1
 goto l_led2
l_led1:
 movlw b'11101111'
 andwf v_m_ioxp1,f
 movlw b'00000100'
 goto l_led_rdy
l_led2:
 movlw b'11111011'
 andwf v_m_ioxp1,f
 movlw b'00010000'

l_led_rdy:
 xorwf v_m_ioxp1,f
 clrf v_ledctr_0
 incf v_ledctr_1
  
l_refresh_skip1:
 return
 
l_refresh_load:
 movf TBLPTRH,w,ACCESS
 call l_push
 movf TBLPTRL,w,ACCESS
 call l_push
 call l_lr1
 call l_pop
 movwf TBLPTRL,ACCESS
 call l_pop
 movwf TBLPTRH,ACCESS
 
 movf v_linemem0,w
 addlw v_m_data
 clrf FSR0H,ACCESS
 movwf FSR0L,ACCESS ; load matrix data pointer into FSR
 movff POSTINC0,v_m_currline0
 movff POSTINC0,v_m_currline1
 movff INDF0,v_m_currline2
 
 movf v_linemem1,w 
 addlw v_m_data
 movwf FSR0L,ACCESS ; load matrix data pointer into FSR

 movff POSTINC0,v_m_currline3
 movff POSTINC0,v_m_currline4
 movff INDF0,v_m_currline5
 movlw b'00000001'
 andwf v_m_currline5,f
 
 movlw high(l_phase_bits)
 movwf PCLATH,ACCESS

 rlncf v_m_phase,w
 call l_phase_bits
 iorwf v_m_currline5,f
 movlw high($+1)
 movwf PCLATH,ACCESS
 
 incf v_m_phase,f
 btfsc v_m_phase,d'2'
 clrf v_m_phase
 
l_refresh_nextphase:
 movlw v_m_currline5
 movwf v_m_serialptr
 movlw d'8'
 movwf v_m_serialctr
 bsf v_status,c_status_serialdata
 
 bcf PORTC,c_PC2_E,ACCESS ; disable E signal
 btfsc v_status,c_status_lcd_more
 call l_lcd_init
 
 return
Usually for testing I use whatever needed in terms of vertical source formatting, later on, superfluous code is removed, and time critical code is simplified. If source is well understood it makes sense to increase horizontal density.
 

THE_RB

Joined Feb 11, 2008
5,438
... If source is well understood it makes sense to increase horizontal density.
Do you really think so? The compiler will usually compile to the same number of vertical ASM instructions as the final result, and speed of execution will be the same.

In my opinion increasing the horizontal density has the one (minor) advantage of taking up less lines on screen, with the disadvantages of being harder to translate and adapt, harder to insert debugging breaks, and harder to mentally refer between C code and ASM output. It also gives you less control of the sequence of operations as the compiler has more say in how a "line" is processed but with vertical code is forced to process in the order you place it.

I know in C (and especially OO C++) class for windows apps etc they like to promote increasing horzontal density but I'm thinking for embedded C programming that more vertical C code definitely suits my needs better.
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
Do you really think so?
...
Yes if I understand the code well, I always try to remove reundant stuff and to clean it up a bit.

For instance this was the original code:
Rich (BB code):
unsigned char
i2c_SendByte(unsigned char byte)
{
	signed char i;

	for(i=7; i>=0; i--)
	{
		SCL_LOW();					/* drive clock low */
		
		/* data hold time = 0, send data now */
        SDA_DIR = ((byte>>i)&0x01);
        if ((byte>>i)&0x01) {		/* bit to send */
			SDA_HIGH();
        }else {
			SDA_LOW();
        }
		__delay_us(I2C_TM_DATA_SU);
		SCL_DIR = I2C_INPUT;		/* float clock high */

		if(i2c_WaitForSCL())		/* wait for clock release */
			return TRUE;			/* bus error */

		__delay_us(I2C_TM_SCL_HIGH);	/* clock high time */
	}
	
	return FALSE;
}
which becomes:

Rich (BB code):
void i2c_SendByte(unsigned char bt)
{unsigned char i,bx;
  bx=bt;
  for(i=0; i<8; i++)
  {SCL_LOW();/* drive clock low */
   bx<<=1;/* data hold time = 0, send data now */
   SDA_DIR = CARRY;
   SDA=CARRY;
   __delay_us(I2C_TM_DATA_SU);
   SCL_DIR = I2C_INPUT;		/* float clock high */
   __delay_us(I2C_TM_SCL_HIGH);	/* clock high time */
}}
I know in C (and especially OO C++) class for windows apps etc they like to promote increasing horzontal density but I'm thinking for embedded C programming that more vertical C code definitely suits my needs better.
Sometimes I have seen things like to comment every assembler line...
It's different if you need to scroll through 100 pages, or only 30 pages.

And if large data tables can be moved into EEPROM they never need to be processed again + disappear from the source.
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
I have looked at Microchip website for pricing, the 18f24j10 is surprisingly inexpensive, lower price than most 16F PICs with 28 pins.

It's a good chip considering the price, 16K memory, and 40 MHz (even using them at nearly 50 MHz seems to be possible).

For instance if you just want a LCD thermometer, counter, clock or voltmeter, you don't need so many bitmaps, and you don't need full motion refresh rate. Serial TFT displays also only cost $6, so this helps to keep BOM reasonable.

Not much more expensive than LED display module, but far more flexible. I think I will stick to this chip for some purposes. And using the hardware serial port, display refresh is surprisingly fast. What the chip can't do is JPEG decoding, there is just not enough RAM.
 

THE_RB

Joined Feb 11, 2008
5,438
... which becomes:

Rich (BB code):
void i2c_SendByte(unsigned char bt)
{unsigned char i,bx;
  bx=bt;
  for(i=0; i<8; i++)
  {SCL_LOW();/* drive clock low */
   bx<<=1;/* data hold time = 0, send data now */
   SDA_DIR = CARRY;
   SDA=CARRY;
   __delay_us(I2C_TM_DATA_SU);
   SCL_DIR = I2C_INPUT;		/* float clock high */
   __delay_us(I2C_TM_SCL_HIGH);	/* clock high time */
}}
...
Thank you for clarifying. I still consider that to be very vertical (and good) coding as each line contains one simple and clear operation.

The "high horizontal density" stuff I personally dislike is when people make lines like this;
percentA = ((adcH<<=8)+adcL)*modifier*100/(scalingX*256);
:)
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
I figured out my GAL programmer also can program serial FLASH chips.

These have 4Mbit = 512 Kbyte. Enough for a decent amount of small bitmaps. Reducing them to 8bits does not really cause a large quality loss, since the palette can still be 24 bits. Well finally it needs to be reduced to 16bits...

Each bitmap takes about 16 Kbyte, simply I read them with the GAL programmer software, and then specify where to put them in memory. Finally all the chips is written at once, which takes minutes for 512K chip.

But it's much better than to convert the data to C or ASM source, and place it inside the PIC memory.

I have succeeded in programming the chip, and to read back data in software!

The code for that is simple, compared to EEPROM (I2C based).
Rich (BB code):
LC2=0;
    set_flash_read_addr(0x000187f0+0x00000083);
    SSP1BUF=0x00;
    while(!SSP1IF);SSP1IF=0;
    LC2=1;
 

Attachments

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
It's 2:29AM but I got it working.

The LCD is a bit messy, it freaks even if it is deselected, when there is traffic on the serial port. Which is also used for the flash chip!

I figured out if the last activity was a row select command, it remains disciplined. Was really weird, pixels appearing all the time for no apparent reason + sometimes the display would go off completely.

Reading BMP raw data from the flash + converting the palette is also lengthy. All 8bit XC8 here, 16bit MCU would be better...

The image on the LCD is not really the same quality like the original 24bit image. It's downconverted to 8bit, with 24bit palette entries. The LCD has upto 18bit resolution, but the data for 24bit is 3x the size, for only little gain in quality.

Maybe I should sell this source code for $5.
I could give it for free, but what would you want to do with it?
Scroll some wallpapers?

And it's still a long way to go, have not tested larger bitmaps yet, there is no offset...

It's even maybe too specialized to give it to other people, means they would not know how to use it or how to change it.
 

Attachments

Top