Lib for FTDI FT800 graphic controller "EVE" The API is changed from the FTDI original names. It use smaller names now. DL() will add something to the display list instead of Ft_App_WrCoCmd_Buffer ... The FTDI programmer Guide is also using this commands.

Dependents:   FT800_RGB_demo FT800_RGB_demo2 FT800_demo_for_habr Temp_&_RH_at_TFT-demo ... more

Fork of FT800 by Peter Drescher

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FT_Gpu_Hal.cpp Source File

FT_Gpu_Hal.cpp

00001 /* mbed Library for FTDI FT800  Enbedded Video Engine "EVE"
00002  * based on Original Code Sample from FTDI
00003  * ported to mbed by Peter Drescher, DC2PD 2014
00004  * Released under the MIT License: http://mbed.org/license/mit 
00005  * 19.09.14 changed to shorter function names  
00006  * FTDI was using very long names. 
00007  * Ft_App_Flush_Co_Buffer -> Flush_Co_Buffer ...  */
00008 
00009 #include "FT_Platform.h"
00010 #include "mbed.h"
00011 #include "FT_LCD_Type.h"
00012 
00013 FT800::FT800(PinName mosi,
00014             PinName miso,
00015             PinName sck,
00016             PinName ss,
00017             PinName intr,
00018             PinName pd)
00019     :
00020      _spi(mosi, miso, sck),
00021      _ss(ss),
00022      _pd(pd),
00023      _f800_isr(InterruptIn(intr))
00024      {
00025          _spi.format(8,0);                  // 8 bit spi mode 0
00026          _spi.frequency(2000000);          // start with 10 Mhz SPI clock
00027          _ss = 1;                           // cs high
00028          _pd = 1;                           // PD high
00029          Bootup();
00030      }
00031 
00032 
00033 ft_bool_t FT800::Bootup(void){
00034     Open();
00035     BootupConfig();
00036 
00037     return(1);
00038     }
00039 
00040 
00041 ft_void_t FT800::BootupConfig(void){
00042     ft_uint8_t chipid;
00043     /* Do a power cycle for safer side */
00044     Powercycle( FT_TRUE);
00045 
00046     /* Access address 0 to wake up the FT800 */
00047     HostCommand( FT_GPU_ACTIVE_M);
00048     Sleep(20);
00049 
00050     /* Set the clk to external clock */
00051     HostCommand( FT_GPU_EXTERNAL_OSC);
00052     Sleep(10);
00053 
00054 
00055     /* Switch PLL output to 48MHz */
00056     HostCommand( FT_GPU_PLL_48M);
00057     Sleep(10);
00058 
00059     /* Do a core reset for safer side */
00060     HostCommand( FT_GPU_CORE_RESET);
00061 
00062     //Read Register ID to check if FT800 is ready.
00063     chipid = Rd8(  REG_ID);
00064     while(chipid != 0x7C)
00065         chipid = Rd8(  REG_ID);
00066 
00067 
00068     // Speed up
00069     _spi.frequency(20000000);           // 20 Mhz SPI clock
00070 
00071     /* Configuration of LCD display */
00072     DispHCycle = my_DispHCycle;
00073     Wr16(  REG_HCYCLE, DispHCycle);
00074     DispHOffset = my_DispHOffset;
00075     Wr16(  REG_HOFFSET, DispHOffset);
00076     DispWidth = my_DispWidth;
00077     Wr16(  REG_HSIZE, DispWidth);
00078     DispHSync0 = my_DispHSync0;
00079     Wr16(  REG_HSYNC0, DispHSync0);
00080     DispHSync1 = my_DispHSync1;
00081     Wr16(  REG_HSYNC1, DispHSync1);
00082     DispVCycle = my_DispVCycle;
00083     Wr16(  REG_VCYCLE, DispVCycle);
00084     DispVOffset = my_DispVOffset;
00085     Wr16(  REG_VOFFSET, DispVOffset);
00086     DispHeight = my_DispHeight;
00087     Wr16(  REG_VSIZE, DispHeight);
00088     DispVSync0 = my_DispVSync0;
00089     Wr16(  REG_VSYNC0, DispVSync0);
00090     DispVSync1 = my_DispVSync1;
00091     Wr16(  REG_VSYNC1, DispVSync1);
00092     DispSwizzle = my_DispSwizzle;
00093     Wr8(  REG_SWIZZLE, DispSwizzle);
00094     DispPCLKPol = my_DispPCLKPol;
00095     Wr8(  REG_PCLK_POL, DispPCLKPol);
00096     Wr8(  REG_CSPREAD, 1);
00097     DispPCLK = my_DispPCLK;
00098     Wr8(  REG_PCLK, DispPCLK);//after this display is visible on the LCD
00099 
00100     Wr16(  REG_PWM_HZ, 1000);
00101 
00102 #ifdef Inv_Backlite               // turn on backlite
00103     Wr16(  REG_PWM_DUTY, 0);
00104 #else
00105     Wr16(  REG_PWM_DUTY, 100);
00106 #endif
00107 
00108     Wr8(  REG_GPIO_DIR,0x82);  //| Rd8( REG_GPIO_DIR));
00109     Wr8(  REG_GPIO,0x080);     //| Rd8( REG_GPIO));
00110 
00111     Wr32(  RAM_DL, CLEAR(1,1,1));
00112     Wr32(  RAM_DL+4, DISPLAY());
00113     Wr32(  REG_DLSWAP,1);
00114 
00115     Wr16(  REG_PCLK, DispPCLK);
00116 
00117     /* Touch configuration - configure the resistance value to 1200 - this value is specific to customer requirement and derived by experiment */
00118     Wr16(  REG_TOUCH_RZTHRESH,1200);
00119 
00120 }
00121 
00122 
00123 
00124 /* API to initialize the SPI interface */
00125 ft_bool_t  FT800::Init()
00126 {
00127     // is done in constructor
00128     return 1;
00129 }
00130 
00131 
00132 ft_bool_t  FT800::Open()
00133 {
00134     cmd_fifo_wp = dl_buff_wp = 0;
00135     status = OPENED;
00136     return 1;
00137 }
00138 
00139 ft_void_t  FT800::Close( )
00140 {
00141     status = CLOSED;
00142 }
00143 
00144 ft_void_t FT800::DeInit()
00145 {
00146 
00147 }
00148 
00149 /*The APIs for reading/writing transfer continuously only with small buffer system*/
00150 ft_void_t  FT800::StartTransfer( FT_GPU_TRANSFERDIR_T rw,ft_uint32_t addr)
00151 {
00152     if (FT_GPU_READ == rw){
00153         _ss = 0;       // cs low
00154         _spi.write(addr >> 16);
00155         _spi.write(addr >> 8);
00156         _spi.write(addr & 0xff);
00157         _spi.write(0); //Dummy Read Byte
00158         status = READING;
00159     }else{
00160         _ss = 0;       // cs low
00161         _spi.write(0x80 | (addr >> 16));
00162         _spi.write(addr >> 8);
00163         _spi.write(addr & 0xff);
00164         status = WRITING;
00165     }
00166 }
00167 
00168 
00169 /*The APIs for writing transfer continuously only*/
00170 ft_void_t  FT800::StartCmdTransfer( FT_GPU_TRANSFERDIR_T rw, ft_uint16_t count)
00171 {
00172     StartTransfer( rw, cmd_fifo_wp + RAM_CMD);
00173 }
00174 
00175 ft_uint8_t  FT800::TransferString( const ft_char8_t *string)
00176 {
00177     ft_uint16_t length = strlen(string);
00178     while(length --){
00179        Transfer8( *string);
00180        string ++;
00181     }
00182     //Append one null as ending flag
00183     Transfer8( 0);
00184     return(1);
00185 }
00186 
00187 
00188 ft_uint8_t  FT800::Transfer8( ft_uint8_t value)
00189 {
00190         return _spi.write(value);
00191 }
00192 
00193 
00194 ft_uint16_t  FT800::Transfer16( ft_uint16_t value)
00195 {
00196     ft_uint16_t retVal = 0;
00197 
00198         if (status == WRITING){
00199         Transfer8( value & 0xFF);//LSB first
00200         Transfer8( (value >> 8) & 0xFF);
00201     }else{
00202         retVal = Transfer8( 0);
00203         retVal |= (ft_uint16_t)Transfer8( 0) << 8;
00204     }
00205 
00206     return retVal;
00207 }
00208 
00209 ft_uint32_t  FT800::Transfer32( ft_uint32_t value)
00210 {
00211     ft_uint32_t retVal = 0;
00212     if (status == WRITING){
00213         Transfer16( value & 0xFFFF);//LSB first
00214         Transfer16( (value >> 16) & 0xFFFF);
00215     }else{
00216         retVal = Transfer16( 0);
00217         retVal |= (ft_uint32_t)Transfer16( 0) << 16;
00218     }
00219     return retVal;
00220 }
00221 
00222 ft_void_t   FT800::EndTransfer( )
00223 {
00224     _ss = 1;
00225     status = OPENED;
00226 }
00227 
00228 
00229 ft_uint8_t  FT800::Rd8( ft_uint32_t addr)
00230 {
00231     ft_uint8_t value;
00232     StartTransfer( FT_GPU_READ,addr);
00233     value = Transfer8( 0);
00234     EndTransfer( );
00235     return value;
00236 }
00237 ft_uint16_t FT800::Rd16( ft_uint32_t addr)
00238 {
00239     ft_uint16_t value;
00240     StartTransfer( FT_GPU_READ,addr);
00241     value = Transfer16( 0);
00242     EndTransfer( );
00243     return value;
00244 }
00245 ft_uint32_t FT800::Rd32( ft_uint32_t addr)
00246 {
00247     ft_uint32_t value;
00248     StartTransfer( FT_GPU_READ,addr);
00249     value = Transfer32( 0);
00250     EndTransfer( );
00251     return value;
00252 }
00253 
00254 ft_void_t FT800::Wr8( ft_uint32_t addr, ft_uint8_t v)
00255 {
00256     StartTransfer( FT_GPU_WRITE,addr);
00257     Transfer8( v);
00258     EndTransfer( );
00259 }
00260 ft_void_t FT800::Wr16( ft_uint32_t addr, ft_uint16_t v)
00261 {
00262     StartTransfer( FT_GPU_WRITE,addr);
00263     Transfer16( v);
00264     EndTransfer( );
00265 }
00266 ft_void_t FT800::Wr32( ft_uint32_t addr, ft_uint32_t v)
00267 {
00268     StartTransfer( FT_GPU_WRITE,addr);
00269     Transfer32( v);
00270     EndTransfer( );
00271 }
00272 
00273 ft_void_t FT800::HostCommand( ft_uint8_t cmd)
00274 {
00275   _ss = 0;
00276   _spi.write(cmd);
00277   _spi.write(0);
00278   _spi.write(0);
00279   _ss = 1;
00280 }
00281 
00282 ft_void_t FT800::ClockSelect( FT_GPU_PLL_SOURCE_T pllsource)
00283 {
00284    HostCommand( pllsource);
00285 }
00286 
00287 ft_void_t FT800::PLL_FreqSelect( FT_GPU_PLL_FREQ_T freq)
00288 {
00289    HostCommand( freq);
00290 }
00291 
00292 ft_void_t FT800::PowerModeSwitch( FT_GPU_POWER_MODE_T pwrmode)
00293 {
00294    HostCommand( pwrmode);
00295 }
00296 
00297 ft_void_t FT800::CoreReset( )
00298 {
00299    HostCommand( 0x68);
00300 }
00301 
00302 
00303 ft_void_t FT800::Updatecmdfifo( ft_uint16_t count)
00304 {
00305      cmd_fifo_wp  = ( cmd_fifo_wp + count) & 4095;
00306     //4 byte alignment
00307      cmd_fifo_wp = ( cmd_fifo_wp + 3) & 0xffc;
00308     Wr16( REG_CMD_WRITE, cmd_fifo_wp);
00309 }
00310 
00311 
00312 ft_uint16_t FT800::fifo_Freespace( )
00313 {
00314     ft_uint16_t fullness,retval;
00315 
00316     fullness = ( cmd_fifo_wp - Rd16( REG_CMD_READ)) & 4095;
00317     retval = (FT_CMD_FIFO_SIZE - 4) - fullness;
00318     return (retval);
00319 }
00320 
00321 ft_void_t FT800::WrCmdBuf( ft_uint8_t *buffer,ft_uint16_t count)
00322 {
00323     ft_uint32_t length =0, SizeTransfered = 0;
00324 
00325 #define MAX_CMD_FIFO_TRANSFER   fifo_Freespace( )
00326     do {
00327         length = count;
00328         if (length > MAX_CMD_FIFO_TRANSFER){
00329             length = MAX_CMD_FIFO_TRANSFER;
00330         }
00331                 CheckCmdBuffer( length);
00332 
00333                 StartCmdTransfer( FT_GPU_WRITE,length);
00334 
00335                 SizeTransfered = 0;
00336         while (length--) {
00337                     Transfer8( *buffer);
00338                     buffer++;
00339                     SizeTransfered ++;
00340         }
00341                 length = SizeTransfered;
00342 
00343         EndTransfer( );
00344         Updatecmdfifo( length);
00345 
00346         WaitCmdfifo_empty( );
00347 
00348         count -= length;
00349     }while (count > 0);
00350 }
00351 
00352 
00353 ft_void_t FT800::WrCmdBufFromFlash( FT_PROGMEM ft_prog_uchar8_t *buffer,ft_uint16_t count)
00354 {
00355     ft_uint32_t length =0, SizeTransfered = 0;
00356 
00357 #define MAX_CMD_FIFO_TRANSFER   fifo_Freespace( )
00358     do {
00359         length = count;
00360         if (length > MAX_CMD_FIFO_TRANSFER){
00361             length = MAX_CMD_FIFO_TRANSFER;
00362         }
00363                 CheckCmdBuffer( length);
00364 
00365                 StartCmdTransfer( FT_GPU_WRITE,length);
00366 
00367 
00368                 SizeTransfered = 0;
00369         while (length--) {
00370                     Transfer8( ft_pgm_read_byte_near(buffer));
00371             buffer++;
00372                     SizeTransfered ++;
00373         }
00374                 length = SizeTransfered;
00375 
00376                 EndTransfer( );
00377         Updatecmdfifo( length);
00378 
00379         WaitCmdfifo_empty( );
00380 
00381         count -= length;
00382     }while (count > 0);
00383 }
00384 
00385 
00386 ft_void_t FT800::CheckCmdBuffer( ft_uint16_t count)
00387 {
00388    ft_uint16_t getfreespace;
00389    do{
00390         getfreespace = fifo_Freespace( );
00391    }while(getfreespace < count);
00392 }
00393 
00394 ft_void_t FT800::WaitCmdfifo_empty( )
00395 {
00396    while(Rd16( REG_CMD_READ) != Rd16( REG_CMD_WRITE));
00397 
00398     cmd_fifo_wp = Rd16( REG_CMD_WRITE);
00399 }
00400 
00401 ft_void_t FT800::WaitLogo_Finish( )
00402 {
00403     ft_int16_t cmdrdptr,cmdwrptr;
00404 
00405     do{
00406          cmdrdptr = Rd16( REG_CMD_READ);
00407          cmdwrptr = Rd16( REG_CMD_WRITE);
00408     }while ((cmdwrptr != cmdrdptr) || (cmdrdptr != 0));
00409      cmd_fifo_wp = 0;
00410 }
00411 
00412 
00413 ft_void_t FT800::ResetCmdFifo( )
00414 {
00415     cmd_fifo_wp = 0;
00416 }
00417 
00418 
00419 ft_void_t FT800::WrCmd32( ft_uint32_t cmd)
00420 {
00421          CheckCmdBuffer( sizeof(cmd));
00422 
00423          Wr32( RAM_CMD +  cmd_fifo_wp,cmd);
00424 
00425          Updatecmdfifo( sizeof(cmd));
00426 }
00427 
00428 
00429 ft_void_t FT800::ResetDLBuffer( )
00430 {
00431             dl_buff_wp = 0;
00432 }
00433 
00434 /* Toggle PD_N pin of FT800 board for a power cycle*/
00435 ft_void_t FT800::Powercycle(  ft_bool_t up)
00436 {
00437     if (up)
00438     {
00439              //Toggle PD_N from low to high for power up switch
00440             _pd = 0;
00441             Sleep(20);
00442 
00443             _pd = 1;
00444             Sleep(20);
00445     }else
00446     {
00447              //Toggle PD_N from high to low for power down switch
00448             _pd = 1;
00449             Sleep(20);
00450 
00451             _pd = 0;
00452             Sleep(20);
00453     }
00454 }
00455 
00456 ft_void_t FT800::WrMemFromFlash( ft_uint32_t addr,const ft_prog_uchar8_t *buffer, ft_uint32_t length)
00457 {
00458     //ft_uint32_t SizeTransfered = 0;
00459 
00460     StartTransfer( FT_GPU_WRITE,addr);
00461 
00462     while (length--) {
00463             Transfer8( ft_pgm_read_byte_near(buffer));
00464         buffer++;
00465     }
00466 
00467     EndTransfer( );
00468 }
00469 
00470 ft_void_t FT800::WrMem( ft_uint32_t addr,const ft_uint8_t *buffer, ft_uint32_t length)
00471 {
00472     //ft_uint32_t SizeTransfered = 0;
00473 
00474     StartTransfer( FT_GPU_WRITE,addr);
00475 
00476     while (length--) {
00477             Transfer8( *buffer);
00478         buffer++;
00479     }
00480 
00481     EndTransfer( );
00482 }
00483 
00484 
00485 ft_void_t FT800::RdMem( ft_uint32_t addr, ft_uint8_t *buffer, ft_uint32_t length)
00486 {
00487     //ft_uint32_t SizeTransfered = 0;
00488 
00489     StartTransfer( FT_GPU_READ,addr);
00490 
00491     while (length--) {
00492        *buffer = Transfer8( 0);
00493        buffer++;
00494     }
00495 
00496     EndTransfer( );
00497 }
00498 
00499 ft_int32_t FT800::Dec2Ascii(ft_char8_t *pSrc,ft_int32_t value)
00500 {
00501     ft_int16_t Length;
00502     ft_char8_t *pdst,charval;
00503     ft_int32_t CurrVal = value,tmpval,i;
00504     ft_char8_t tmparray[16],idx = 0;
00505 
00506     Length = strlen(pSrc);
00507     pdst = pSrc + Length;
00508 
00509     if(0 == value)
00510     {
00511         *pdst++ = '0';
00512         *pdst++ = '\0';
00513         return 0;
00514     }
00515 
00516     if(CurrVal < 0)
00517     {
00518         *pdst++ = '-';
00519         CurrVal = - CurrVal;
00520     }
00521     /* insert the value */
00522     while(CurrVal > 0){
00523         tmpval = CurrVal;
00524         CurrVal /= 10;
00525         tmpval = tmpval - CurrVal*10;
00526         charval = '0' + tmpval;
00527         tmparray[idx++] = charval;
00528     }
00529 
00530     for(i=0;i<idx;i++)
00531     {
00532         *pdst++ = tmparray[idx - i - 1];
00533     }
00534     *pdst++ = '\0';
00535 
00536     return 0;
00537 }
00538 
00539 
00540 ft_void_t FT800::Sleep(ft_uint16_t ms)
00541 {
00542     wait_ms(ms);
00543 }
00544 
00545 ft_void_t FT800::Sound_ON(){
00546      Wr8(  REG_GPIO, 0x02 | Rd8( REG_GPIO));
00547 }
00548 
00549 ft_void_t FT800::Sound_OFF(){
00550      Wr8(  REG_GPIO, 0xFD & Rd8( REG_GPIO));
00551 }
00552 
00553 
00554 
00555