FTDI Community

Please login or register.

Login with username, password and session length.
Advanced Search  

News:



Welcome to the FTDI Community!

Please read our Welcome Note

Technical Support enquires
please contact the team
@ FTDI Support


Author Topic: FT813 how to update a portion of a display  (Read 1268 times)

Farid

  • Newbie
  • *
  • Posts: 8
    • View Profile
FT813 how to update a portion of a display
« on: April 18, 2018, 06:31:39 PM »

Can anyone tell me how to update only a portion of an LCD display. In my case, I need to display a numeric value on the main display once a user touches a certain button.

Now I am just transmitting the entire display content every 200 ms(which I dont think is efficient)

Thank you!
Logged

FTDI Community

  • Administrator
  • Full Member
  • *****
  • Posts: 177
    • View Profile
Re: FT813 how to update a portion of a display
« Reply #1 on: April 20, 2018, 09:21:20 AM »

Hello,

We have a description of the Append technique in the application note below:

http://www.ftdichip.com/Support/Documents/AppNotes/AN_340_FT800_Optimising%20screen%20updates%20with%20Macro%20and%20Append.pdf

This allows you to store the static parts of the screen and re-send only the numbers each time. The same technique works for both FT80x and FT81x.

Best Regards, FTDI Community

Logged

Farid

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: FT813 how to update a portion of a display
« Reply #2 on: April 21, 2018, 01:40:25 AM »

Hi,

Thank you so much for your reply. It's a helpful.

I managed to implement the append function; however, I was not able to see all of my display list. for example I am able to see only 3 buttons instead of 5 button, an no rectangle or dot.
I think the issue here is that I run out of RAM. I tried changing the ram space, but with no success. This is the function I used to change ram space:

cmd_memset(0, 0, 10 * 2048);


below is the display list:

ft800memWrite32(RAM_CMD + cmdOffset, (CMD_DLSTART));   // Start the display list
cmdOffset = incCMDOffset(cmdOffset, 4);                        

ft800memWrite32(RAM_CMD + cmdOffset, DL_CLEAR_RGB);   // same as CLEAR_COLOR_RGB(0, 0, 0) Start the display list
cmdOffset = incCMDOffset(cmdOffset, 4);      
   
ft800memWrite32(RAM_CMD + cmdOffset, (DL_CLEAR_RGB | BLUE));   // same as CLEAR_COLOR_RGB(0, 0, 0) Start the display list
cmdOffset = incCMDOffset(cmdOffset, 4);      
              
ft800memWrite32(RAM_CMD + cmdOffset, CLEAR(1,1,1))  ; 
cmdOffset = incCMDOffset(cmdOffset, 4);   
      
ft800memWrite32(RAM_CMD + cmdOffset, TAG_MASK(1)); 
cmdOffset = incCMDOffset(cmdOffset, 4);
      
ft800memWrite32(RAM_CMD + cmdOffset, TAG(10)); 
cmdOffset = incCMDOffset(cmdOffset, 4);         
DisplayButton(10,10, 180, 60, 24,  OPT_FLAT, &Button1String[0],GREY,BLACK);
      
ft800memWrite32(RAM_CMD + cmdOffset, TAG(20)); 
cmdOffset = incCMDOffset(cmdOffset, 4);   
DisplayButton(10,110, 180, 60, 24, OPT_FLAT, &Button2String[0],GREY,BLACK);
      
ft800memWrite32(RAM_CMD + cmdOffset, TAG(30)); 
cmdOffset = incCMDOffset(cmdOffset, 4);   
DisplayButton(10,210, 180, 60, 24, OPT_FLAT, &Button3String[0],GREY,BLACK);
      
ft800memWrite32(RAM_CMD + cmdOffset, TAG(40)); 
cmdOffset = incCMDOffset(cmdOffset, 4);   
DisplayButton(10,310, 180, 60, 24, OPT_FLAT, &Button4String[0],GREY,BLACK);
      
ft800memWrite32(RAM_CMD + cmdOffset, TAG(50)); 
cmdOffset = incCMDOffset(cmdOffset, 4);
DisplayButton(10,410, 180, 60, 24, OPT_FLAT, &Button5String[0],GREY,BLACK);
      
ft800memWrite32(RAM_CMD + cmdOffset, TAG_MASK(0)); 
cmdOffset = incCMDOffset(cmdOffset, 4);
      
DisplayDOT(point_x1,point_y1,color,point_size);
DisplayRECT(220,20,300,60,WHITE,10);
ft800memWrite32(RAM_CMD + cmdOffset, COLOR_RGB(255,0,0));                                                                                      
cmdOffset = incCMDOffset(cmdOffset, 4);
Logged

Farid

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: FT813 how to update a portion of a display
« Reply #3 on: April 23, 2018, 07:15:26 PM »

ISSUE#1:

further debugging have showed me that the memset function does not work: here is how I defined, and I passed the following parameters top it:
    cmd_memset(0, 0, 100*1024L);                           // Set a block of memory to zeros between address 0 and address 10*1024
    WaitCmdFifoEmpty();

If I comment out cmd_memset above, I still see the same issues as described in the previous post.

void cmd_memset(uint32_t ptr, uint32_t value, uint32_t num)
{                     
   ft800memWrite32(RAM_CMD + cmdOffset, CMD_MEMSET);
   cmdOffset = incCMDOffset(cmdOffset, 4);   
   
   ft800memWrite32(RAM_CMD + cmdOffset, ptr);
   cmdOffset = incCMDOffset(cmdOffset, 4);
   
   ft800memWrite32(RAM_CMD + cmdOffset, value);
   cmdOffset = incCMDOffset(cmdOffset, 4);
   
   ft800memWrite32(RAM_CMD + cmdOffset, num);
   cmdOffset = incCMDOffset(cmdOffset, 4);
}

ISSUE#2:

Another Issue that I run out into is that: dloffset = ft800memRead16(REG_CMD_DL); this functions always returns zero. So to get around this, I have to track the offset and use that value as shown below:
dloffset= (uint16_t)cmdOffset;
      
ft800memWrite32(RAM_CMD + cmdOffset, CMD_MEMCPY);  // Command to copy a block of memory within the FT800
cmdOffset = incCMDOffset(cmdOffset, 4);

ft800memWrite32(RAM_CMD + cmdOffset, 100*1024L);  // First parameter is destination, copy to address 1,000 decimal
cmdOffset = incCMDOffset(cmdOffset, 4);
       
ft800memWrite32(RAM_CMD + cmdOffset, RAM_DL);
cmdOffset = incCMDOffset(cmdOffset, 4);
      
ft800memWrite32(RAM_CMD + cmdOffset,dloffset);
cmdOffset = incCMDOffset(cmdOffset, 4);
      
ft800memWrite16(REG_CMD_WRITE, (cmdOffset));               // Update the ring buffer pointer so the graphics processor starts executing

Logged

Farid

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: FT813 how to update a portion of a display
« Reply #4 on: April 25, 2018, 10:46:49 PM »

You anybody comments on my previous issues?

I have noticed in my code that I am always reading 0 for the offset using this piece of code:
while(0!=ft813memRead16(REG_CMD_READ));

again here is how is setup the static backgound

void initMainStaticBackground(void)   
{   
WaitCmdFifoEmpty();  //wait for FIFO read/write

ft813memWrite32(RAM_CMD + cmdOffset, (CMD_DLSTART));   // Start the display list
cmdOffset = incCMDOffset(cmdOffset, 4);   
   
 /* ------------------------------------------------------------------------------------------------------------------------------
Initialise a block of grahics RAM memory where the static part will be stored. Ensure that this does not overlap with any memory
used to store fonts or bitmaps etc. in the application
------------------------------------------------------------------------------------------------------------------------------ */   
cmd_memset(0, 0, 300*1024);                           // Set a block of memory to zeros between address 0 and address 10*1024
WaitCmdFifoEmpty();
 
ft813memWrite16(REG_CMD_WRITE, (cmdOffset));               // Update the ring buffer pointer so the graphics processor starts executing
   
/* ------------------------------------------------------------------------------------------------------------------------------
Create the static part of the display and store it within the ft813's RAM_G Send a co-processor list containing the static parts of
the display to the ft813 using the command FIFO in the normal way. The list does not however terminate with the usual
Display and Swap commands since the dynamic part of the list will be appended later.
 
The ft813 will now create the display list based on these commands as per normal ft813 operation and so the resulting display list
will now be in RAM_DL. This is the display list is needed to draw the static part of the display.       
------------------------------------------------------------------------------------------------------------------------------ */
      
ft813memWrite32(RAM_CMD + cmdOffset, DL_CLEAR_RGB);   // same as CLEAR_COLOR_RGB(0, 0, 0) Start the display list
cmdOffset = incCMDOffset(cmdOffset, 4);      
   
ft813memWrite32(RAM_CMD + cmdOffset, (DL_CLEAR_RGB | BLUE));   // same as CLEAR_COLOR_RGB(0, 0, 0) Start the display list
cmdOffset = incCMDOffset(cmdOffset, 4);      
              
ft813memWrite32(RAM_CMD + cmdOffset, CLEAR(1,1,1))  ; 
cmdOffset = incCMDOffset(cmdOffset, 4);   

ft813memWrite32(RAM_CMD + cmdOffset, TAG_MASK(1)); 
cmdOffset = incCMDOffset(cmdOffset, 4);
      
ft813memWrite32(RAM_CMD + cmdOffset, TAG(10)); 
cmdOffset = incCMDOffset(cmdOffset, 4);         
DisplayButton(10,10, 180, 60, 24,  OPT_FLAT, &Button1String[0],GREY,BLACK);
      
ft813memWrite32(RAM_CMD + cmdOffset, TAG(20)); 
cmdOffset = incCMDOffset(cmdOffset, 4);   
DisplayButton(10,110, 180, 60, 24, OPT_FLAT, &Button2String[0],GREY,BLACK);
      
ft813memWrite32(RAM_CMD + cmdOffset, TAG(30)); 
cmdOffset = incCMDOffset(cmdOffset, 4);   
DisplayButton(10,210, 180, 60, 24, OPT_FLAT, &Button3String[0],GREY,BLACK);

ft813memWrite32(RAM_CMD + cmdOffset, TAG(40)); 
cmdOffset = incCMDOffset(cmdOffset, 4);   
DisplayButton(10,310, 180, 60, 24, OPT_FLAT, &Button4String[0],GREY,BLACK);
   
ft813memWrite32(RAM_CMD + cmdOffset, TAG(50)); 
cmdOffset = incCMDOffset(cmdOffset, 4);
DisplayButton(10,410, 180, 60, 24, OPT_FLAT, &Button5String[0],GREY,BLACK);
      
ft813memWrite32(RAM_CMD + cmdOffset, TAG_MASK(0)); 
cmdOffset = incCMDOffset(cmdOffset, 4);

DisplayRECT(220,20,300,60,WHITE,10);
      

 /* ------------------------------------------------------------------------------------------------------------------------------
Read the REG_CMD_DL register to determine the end address for this new display list (as an offset from the start of RAM_DL). This
equates to the size of the display list and is needed for the following mem copy.       
------------------------------------------------------------------------------------------------------------------------------ */
WaitCmdFifoEmpty();

//    while(0!=ft813memRead16(REG_CMD_READ));

dloffset = ft813memRead16(REG_CMD_DL);
      
dloffset= (uint16_t)cmdOffset;
      
cmd_memcpy(4000L, RAM_DL, dloffset);  // copy a number of bytes equal to cmdoffset value from RAM_DL to 1000L address
               
ft813memWrite16(REG_CMD_WRITE, (cmdOffset));               // Update the ring buffer pointer so the graphics processor starts executing      
}
Logged

FTDI Community

  • Administrator
  • Full Member
  • *****
  • Posts: 177
    • View Profile
Re: FT813 how to update a portion of a display
« Reply #5 on: April 26, 2018, 10:09:36 AM »

Hello Farid,

The code below should help when storing the static list.

Note that after sending commands, you should update the REG_CMD_WRITE and then wait for completion of the commands.

In general,

- Await the buffer empty (WaitCmdFifoEmpty)
- Send commands beginning at current REG_CMD_WRITE pointer value (keeping track of offset with each command)
- Update REG_CMD_WRITE to make the co-pro execute them
- Await the buffer empty (WaitCmdFifoEmpty) i.e.. when REG_CMD_READ catches up with your updated REG_CMD_WRITE value



Code: [Select]
void initMainStaticBackground(void)   
{   
// try without this first
//WaitCmdFifoEmpty();  //wait for FIFO read/write
//cmd_memset(0, 0, 300*1024);                           
//ft813memWrite16(REG_CMD_WRITE, (cmdOffset));
//WaitCmdFifoEmpty();


//########### Await FIFO Empty ###########

WaitCmdFifoEmpty();  //wait for FIFO read/write

//########### Create the static list in CMD FIFO ###########

ft813memWrite32(RAM_CMD + cmdOffset, (CMD_DLSTART));   // Start the display list
cmdOffset = incCMDOffset(cmdOffset, 4);   
       
//ft813memWrite32(RAM_CMD + cmdOffset, DL_CLEAR_RGB);   // same as CLEAR_COLOR_RGB(0, 0, 0) Start the display list
//cmdOffset = incCMDOffset(cmdOffset, 4);     
   
//ft813memWrite32(RAM_CMD + cmdOffset, (DL_CLEAR_RGB | BLUE));   // same as CLEAR_COLOR_RGB(0, 0, 0) Start the display list
//cmdOffset = incCMDOffset(cmdOffset, 4);     
               
//ft813memWrite32(RAM_CMD + cmdOffset, CLEAR(1,1,1))  ; 
//cmdOffset = incCMDOffset(cmdOffset, 4);   

ft813memWrite32(RAM_CMD + cmdOffset, TAG_MASK(1)); 
cmdOffset = incCMDOffset(cmdOffset, 4);
     
ft813memWrite32(RAM_CMD + cmdOffset, TAG(10)); 
cmdOffset = incCMDOffset(cmdOffset, 4);         
DisplayButton(10,10, 180, 60, 24,  OPT_FLAT, &Button1String[0],GREY,BLACK);
     
ft813memWrite32(RAM_CMD + cmdOffset, TAG(20)); 
cmdOffset = incCMDOffset(cmdOffset, 4);   
DisplayButton(10,110, 180, 60, 24, OPT_FLAT, &Button2String[0],GREY,BLACK);
     
ft813memWrite32(RAM_CMD + cmdOffset, TAG(30)); 
cmdOffset = incCMDOffset(cmdOffset, 4);   
DisplayButton(10,210, 180, 60, 24, OPT_FLAT, &Button3String[0],GREY,BLACK);

ft813memWrite32(RAM_CMD + cmdOffset, TAG(40)); 
cmdOffset = incCMDOffset(cmdOffset, 4);   
DisplayButton(10,310, 180, 60, 24, OPT_FLAT, &Button4String[0],GREY,BLACK);
   
ft813memWrite32(RAM_CMD + cmdOffset, TAG(50)); 
cmdOffset = incCMDOffset(cmdOffset, 4);
DisplayButton(10,410, 180, 60, 24, OPT_FLAT, &Button5String[0],GREY,BLACK);
     
ft813memWrite32(RAM_CMD + cmdOffset, TAG_MASK(0)); 
cmdOffset = incCMDOffset(cmdOffset, 4);

DisplayRECT(220,20,300,60,WHITE,10);
     
//########### Execute the commands to make the display list in RAM_DL ###########

ft813memWrite16(REG_CMD_WRITE, (cmdOffset));               // Update the ring buffer pointer so the graphics processor starts executing 

//########### Await completion ###########

WaitCmdFifoEmpty();

//########### Find the end of the new DL ###########

dloffset = ft813memRead16(REG_CMD_DL);


//########### Copy the created DL into RAM_G @ address 4000 in this case ###########

// Could use your command
// ft813memWrite32(RAM_CMD + cmdOffset, CMD_MEMCPY(4000L, RAM_DL, dloffset));
// instead of this code below

ft813memWrite32(RAM_CMD + cmdOffset, CMD_MEMCPY);
cmdOffset = incCMDOffset(cmdOffset, 4);
ft813memWrite32(RAM_CMD + cmdOffset, 4000L);
cmdOffset = incCMDOffset(cmdOffset, 4);
ft813memWrite32(RAM_CMD + cmdOffset, RAM_DL);
cmdOffset = incCMDOffset(cmdOffset, 4);
ft813memWrite32(RAM_CMD + cmdOffset, dloffset);
cmdOffset = incCMDOffset(cmdOffset, 4);

ft813memWrite16(REG_CMD_WRITE, (cmdOffset));

WaitCmdFifoEmpty();

//########### Your static part of the list will now be available ###########



Regards, FTDI Community



Logged

Farid

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: FT813 how to update a portion of a display
« Reply #6 on: April 26, 2018, 11:11:36 PM »

Hi,

Thank you so much for the help! Now I am able to use the saved static display in my while loop.

I am also interested in setting up a few static displays to be used in different user display selections. Could you please add some lines of code to the previous code to demonstrate that.

Thanks,
Farid
Logged

FTDI Community

  • Administrator
  • Full Member
  • *****
  • Posts: 177
    • View Profile
Re: FT813 how to update a portion of a display
« Reply #7 on: April 27, 2018, 01:08:47 PM »

Hi,
Each part is saved in a similar way. For example, as shown below we create 2 static sections.


Code: [Select]
void initMainStaticBackground1(void)   
{   

//########### Await FIFO Empty ###########

WaitCmdFifoEmpty();  //wait for FIFO read/write

//########### Create the static list in CMD FIFO ###########

ft813memWrite32(RAM_CMD + cmdOffset, (CMD_DLSTART));   // Start the display list
cmdOffset = incCMDOffset(cmdOffset, 4);   
       
[Your other commands here]
[Not including CLEAR(1,1,1) or DISPLAY or SWAP]
     

//########### Execute the commands to make the display list in RAM_DL ###########

ft813memWrite16(REG_CMD_WRITE, (cmdOffset));               // Update the ring buffer pointer so the graphics processor starts executing 

//########### Await completion ###########

WaitCmdFifoEmpty();

//########### Find the end of the new DL ###########

Static1Length = ft813memRead16(REG_CMD_DL);


//########### Copy the created DL into RAM_G @ address 4000 in this case ###########

// Could use your command
// ft813memWrite32(RAM_CMD + cmdOffset, CMD_MEMCPY(4000L, RAM_DL, dloffset));
// instead of this code below

ft813memWrite32(RAM_CMD + cmdOffset, CMD_MEMCPY);
cmdOffset = incCMDOffset(cmdOffset, 4);
ft813memWrite32(RAM_CMD + cmdOffset, StaticLocation1);
cmdOffset = incCMDOffset(cmdOffset, 4);
ft813memWrite32(RAM_CMD + cmdOffset, RAM_DL);
cmdOffset = incCMDOffset(cmdOffset, 4);
ft813memWrite32(RAM_CMD + cmdOffset, Static1Length);
cmdOffset = incCMDOffset(cmdOffset, 4);

ft813memWrite16(REG_CMD_WRITE, (cmdOffset));

WaitCmdFifoEmpty();

//########### Your static part of the list will now be available ###########
}




void initMainStaticBackground2(void)   
{   

//########### Await FIFO Empty ###########

WaitCmdFifoEmpty();  //wait for FIFO read/write

//########### Create the static list in CMD FIFO ###########

ft813memWrite32(RAM_CMD + cmdOffset, (CMD_DLSTART));   // Start the display list
cmdOffset = incCMDOffset(cmdOffset, 4);   
       
[Your other commands here]
[Not including CLEAR(1,1,1) or DISPLAY or SWAP]
     

//########### Execute the commands to make the display list in RAM_DL ###########

ft813memWrite16(REG_CMD_WRITE, (cmdOffset));               // Update the ring buffer pointer so the graphics processor starts executing 

//########### Await completion ###########

WaitCmdFifoEmpty();

//########### Find the end of the new DL ###########

Static2Length= ft813memRead16(REG_CMD_DL);


//########### Copy the created DL into RAM_G @ address 4000 in this case ###########

// Could use your command
// ft813memWrite32(RAM_CMD + cmdOffset, CMD_MEMCPY(4000L, RAM_DL, dloffset));
// instead of this code below

ft813memWrite32(RAM_CMD + cmdOffset, CMD_MEMCPY);
cmdOffset = incCMDOffset(cmdOffset, 4);
ft813memWrite32(RAM_CMD + cmdOffset, StaticLocation2);
cmdOffset = incCMDOffset(cmdOffset, 4);
ft813memWrite32(RAM_CMD + cmdOffset, RAM_DL);
cmdOffset = incCMDOffset(cmdOffset, 4);
ft813memWrite32(RAM_CMD + cmdOffset, Static2Length)
cmdOffset = incCMDOffset(cmdOffset, 4);

ft813memWrite16(REG_CMD_WRITE, (cmdOffset));

WaitCmdFifoEmpty();

//########### Your static part of the list will now be available ###########
}




Your code should keep a note of StaticLocation1, Static1Length, StaticLocation2, Static2Length, as these are required when recalling the sections with Append.

Ensure that the saved sections don't overlap. You can assure this by taking account the size of each static section (e.g.  end of static section1 would be StaticLocation1 + Static1Length)

We have an example in the application note below (see 4.3.2 onwards) where we make a chart using 2 static sections (a background and a scale) and then add the line. This is in Arduino format but uses the same techniques.
http://brtchip.com/wp-content/uploads/Support/Documentation/Application_Notes/Modules/EVE/AN_356-FT800-Interfacing-I2C-Sensor-to-VM800P.pdf

Regards, FTDI Community



 
Logged