Ok for EveConnect
Dependents: FT800_RGB_demo-for_ConnectEve
Diff: FT_Gpu_Hal.cpp
- Revision:
- 0:352efe1d072f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FT_Gpu_Hal.cpp Mon Mar 11 19:14:19 2019 +0000 @@ -0,0 +1,551 @@ +/* mbed Library for FTDI FT800 Enbedded Video Engine "EVE" + * based on Original Code Sample from FTDI + * ported to mbed by Peter Drescher, DC2PD 2014 + * Released under the MIT License: http://mbed.org/license/mit + * 19.09.14 changed to shorter function names + * FTDI was using very long names. + * Ft_App_Flush_Co_Buffer -> Flush_Co_Buffer ... */ + +#include "FT_Platform.h" +#include "mbed.h" +#include "FT_LCD_Type.h" + +FT800::FT800(PinName mosi, + PinName miso, + PinName sck, + PinName ss, + PinName intr, + PinName pd) + :_spi(mosi, miso, sck), + _ss(ss), + _f800_isr(InterruptIn(intr)), + _pd(pd) + { + _spi.format(8,0); // 8 bit spi mode 0 + _spi.frequency(10000000); // start with 10 Mhz SPI clock + _ss = 1; // cs high + _pd = 1; // PD high + Bootup(); + } + + +ft_bool_t FT800::Bootup(void){ + Open(); + BootupConfig(); + + return(1); + } + + +ft_void_t FT800::BootupConfig(void){ + ft_uint8_t chipid; + /* Do a power cycle for safer side */ + Powercycle( FT_TRUE); + + /* Access address 0 to wake up the FT800 */ + HostCommand( FT_GPU_ACTIVE_M); + Sleep(20); + + /* Set the clk to external clock */ + HostCommand( FT_GPU_EXTERNAL_OSC); + Sleep(10); + + + /* Switch PLL output to 48MHz */ + HostCommand( FT_GPU_PLL_48M); + Sleep(10); + + /* Do a core reset for safer side */ + HostCommand( FT_GPU_CORE_RESET); + + //Read Register ID to check if FT800 is ready. + chipid = Rd8( REG_ID); + while(chipid != 0x7C) + chipid = Rd8( REG_ID); + + + // Speed up + _spi.frequency(16000000); // 20 Mhz SPI clock + + /* Configuration of LCD display */ + DispHCycle = my_DispHCycle; + Wr16( REG_HCYCLE, DispHCycle); + DispHOffset = my_DispHOffset; + Wr16( REG_HOFFSET, DispHOffset); + DispWidth = my_DispWidth; + Wr16( REG_HSIZE, DispWidth); + DispHSync0 = my_DispHSync0; + Wr16( REG_HSYNC0, DispHSync0); + DispHSync1 = my_DispHSync1; + Wr16( REG_HSYNC1, DispHSync1); + DispVCycle = my_DispVCycle; + Wr16( REG_VCYCLE, DispVCycle); + DispVOffset = my_DispVOffset; + Wr16( REG_VOFFSET, DispVOffset); + DispHeight = my_DispHeight; + Wr16( REG_VSIZE, DispHeight); + DispVSync0 = my_DispVSync0; + Wr16( REG_VSYNC0, DispVSync0); + DispVSync1 = my_DispVSync1; + Wr16( REG_VSYNC1, DispVSync1); + DispSwizzle = my_DispSwizzle; + Wr8( REG_SWIZZLE, DispSwizzle); + DispPCLKPol = my_DispPCLKPol; + Wr8( REG_PCLK_POL, DispPCLKPol); + Wr8( REG_CSPREAD, 1); + DispPCLK = my_DispPCLK; + Wr8( REG_PCLK, DispPCLK);//after this display is visible on the LCD + + Wr16( REG_PWM_HZ, 1000); + +#ifdef Inv_Backlite // turn on backlite + Wr16( REG_PWM_DUTY, 0); +#else + Wr16( REG_PWM_DUTY, 100); +#endif + + Wr8( REG_GPIO_DIR,0x82); //| Rd8( REG_GPIO_DIR)); + Wr8( REG_GPIO,0x080); //| Rd8( REG_GPIO)); + + Wr32( RAM_DL, CLEAR(1,1,1)); + Wr32( RAM_DL+4, DISPLAY()); + Wr32( REG_DLSWAP,1); + + Wr16( REG_PCLK, DispPCLK); + + /* Touch configuration - configure the resistance value to 1200 - this value is specific to customer requirement and derived by experiment */ + Wr16( REG_TOUCH_RZTHRESH,1200); + +} + + + +/* API to initialize the SPI interface */ +ft_bool_t FT800::Init() +{ + // is done in constructor + return 1; +} + + +ft_bool_t FT800::Open() +{ + cmd_fifo_wp = dl_buff_wp = 0; + status = OPENED; + return 1; +} + +ft_void_t FT800::Close( ) +{ + status = CLOSED; +} + +ft_void_t FT800::DeInit() +{ + +} + +/*The APIs for reading/writing transfer continuously only with small buffer system*/ +ft_void_t FT800::StartTransfer( FT_GPU_TRANSFERDIR_T rw,ft_uint32_t addr) +{ + if (FT_GPU_READ == rw){ + _ss = 0; // cs low + _spi.write(addr >> 16); + _spi.write(addr >> 8); + _spi.write(addr & 0xff); + _spi.write(0); //Dummy Read Byte + status = READING; + }else{ + _ss = 0; // cs low + _spi.write(0x80 | (addr >> 16)); + _spi.write(addr >> 8); + _spi.write(addr & 0xff); + status = WRITING; + } +} + + +/*The APIs for writing transfer continuously only*/ +ft_void_t FT800::StartCmdTransfer( FT_GPU_TRANSFERDIR_T rw, ft_uint16_t count) +{ + StartTransfer( rw, cmd_fifo_wp + RAM_CMD); +} + +ft_uint8_t FT800::TransferString( const ft_char8_t *string) +{ + ft_uint16_t length = strlen(string); + while(length --){ + Transfer8( *string); + string ++; + } + //Append one null as ending flag + Transfer8( 0); + return(1); +} + + +ft_uint8_t FT800::Transfer8( ft_uint8_t value) +{ + return _spi.write(value); +} + + +ft_uint16_t FT800::Transfer16( ft_uint16_t value) +{ + ft_uint16_t retVal = 0; + + if (status == WRITING){ + Transfer8( value & 0xFF);//LSB first + Transfer8( (value >> 8) & 0xFF); + }else{ + retVal = Transfer8( 0); + retVal |= (ft_uint16_t)Transfer8( 0) << 8; + } + + return retVal; +} + +ft_uint32_t FT800::Transfer32( ft_uint32_t value) +{ + ft_uint32_t retVal = 0; + if (status == WRITING){ + Transfer16( value & 0xFFFF);//LSB first + Transfer16( (value >> 16) & 0xFFFF); + }else{ + retVal = Transfer16( 0); + retVal |= (ft_uint32_t)Transfer16( 0) << 16; + } + return retVal; +} + +ft_void_t FT800::EndTransfer( ) +{ + _ss = 1; + status = OPENED; +} + + +ft_uint8_t FT800::Rd8( ft_uint32_t addr) +{ + ft_uint8_t value; + StartTransfer( FT_GPU_READ,addr); + value = Transfer8( 0); + EndTransfer( ); + return value; +} +ft_uint16_t FT800::Rd16( ft_uint32_t addr) +{ + ft_uint16_t value; + StartTransfer( FT_GPU_READ,addr); + value = Transfer16( 0); + EndTransfer( ); + return value; +} +ft_uint32_t FT800::Rd32( ft_uint32_t addr) +{ + ft_uint32_t value; + StartTransfer( FT_GPU_READ,addr); + value = Transfer32( 0); + EndTransfer( ); + return value; +} + +ft_void_t FT800::Wr8( ft_uint32_t addr, ft_uint8_t v) +{ + StartTransfer( FT_GPU_WRITE,addr); + Transfer8( v); + EndTransfer( ); +} +ft_void_t FT800::Wr16( ft_uint32_t addr, ft_uint16_t v) +{ + StartTransfer( FT_GPU_WRITE,addr); + Transfer16( v); + EndTransfer( ); +} +ft_void_t FT800::Wr32( ft_uint32_t addr, ft_uint32_t v) +{ + StartTransfer( FT_GPU_WRITE,addr); + Transfer32( v); + EndTransfer( ); +} + +ft_void_t FT800::HostCommand( ft_uint8_t cmd) +{ + _ss = 0; + _spi.write(cmd); + _spi.write(0); + _spi.write(0); + _ss = 1; +} + +ft_void_t FT800::ClockSelect( FT_GPU_PLL_SOURCE_T pllsource) +{ + HostCommand( pllsource); +} + +ft_void_t FT800::PLL_FreqSelect( FT_GPU_PLL_FREQ_T freq) +{ + HostCommand( freq); +} + +ft_void_t FT800::PowerModeSwitch( FT_GPU_POWER_MODE_T pwrmode) +{ + HostCommand( pwrmode); +} + +ft_void_t FT800::CoreReset( ) +{ + HostCommand( 0x68); +} + + +ft_void_t FT800::Updatecmdfifo( ft_uint16_t count) +{ + cmd_fifo_wp = ( cmd_fifo_wp + count) & 4095; + //4 byte alignment + cmd_fifo_wp = ( cmd_fifo_wp + 3) & 0xffc; + Wr16( REG_CMD_WRITE, cmd_fifo_wp); +} + + +ft_uint16_t FT800::fifo_Freespace( ) +{ + ft_uint16_t fullness,retval; + + fullness = ( cmd_fifo_wp - Rd16( REG_CMD_READ)) & 4095; + retval = (FT_CMD_FIFO_SIZE - 4) - fullness; + return (retval); +} + +ft_void_t FT800::WrCmdBuf( ft_uint8_t *buffer,ft_uint16_t count) +{ + ft_uint32_t length =0, SizeTransfered = 0; + +#define MAX_CMD_FIFO_TRANSFER fifo_Freespace( ) + do { + length = count; + if (length > MAX_CMD_FIFO_TRANSFER){ + length = MAX_CMD_FIFO_TRANSFER; + } + CheckCmdBuffer( length); + + StartCmdTransfer( FT_GPU_WRITE,length); + + SizeTransfered = 0; + while (length--) { + Transfer8( *buffer); + buffer++; + SizeTransfered ++; + } + length = SizeTransfered; + + EndTransfer( ); + Updatecmdfifo( length); + + WaitCmdfifo_empty( ); + + count -= length; + }while (count > 0); +} + + +ft_void_t FT800::WrCmdBufFromFlash( FT_PROGMEM ft_prog_uchar8_t *buffer,ft_uint16_t count) +{ + ft_uint32_t length =0, SizeTransfered = 0; + +#define MAX_CMD_FIFO_TRANSFER fifo_Freespace( ) + do { + length = count; + if (length > MAX_CMD_FIFO_TRANSFER){ + length = MAX_CMD_FIFO_TRANSFER; + } + CheckCmdBuffer( length); + + StartCmdTransfer( FT_GPU_WRITE,length); + + + SizeTransfered = 0; + while (length--) { + Transfer8( ft_pgm_read_byte_near(buffer)); + buffer++; + SizeTransfered ++; + } + length = SizeTransfered; + + EndTransfer( ); + Updatecmdfifo( length); + + WaitCmdfifo_empty( ); + + count -= length; + }while (count > 0); +} + + +ft_void_t FT800::CheckCmdBuffer( ft_uint16_t count) +{ + ft_uint16_t getfreespace; + do{ + getfreespace = fifo_Freespace( ); + }while(getfreespace < count); +} + +ft_void_t FT800::WaitCmdfifo_empty( ) +{ + while(Rd16( REG_CMD_READ) != Rd16( REG_CMD_WRITE)); + + cmd_fifo_wp = Rd16( REG_CMD_WRITE); +} + +ft_void_t FT800::WaitLogo_Finish( ) +{ + ft_int16_t cmdrdptr,cmdwrptr; + + do{ + cmdrdptr = Rd16( REG_CMD_READ); + cmdwrptr = Rd16( REG_CMD_WRITE); + }while ((cmdwrptr != cmdrdptr) || (cmdrdptr != 0)); + cmd_fifo_wp = 0; +} + + +ft_void_t FT800::ResetCmdFifo( ) +{ + cmd_fifo_wp = 0; +} + + +ft_void_t FT800::WrCmd32( ft_uint32_t cmd) +{ + CheckCmdBuffer( sizeof(cmd)); + + Wr32( RAM_CMD + cmd_fifo_wp,cmd); + + Updatecmdfifo( sizeof(cmd)); +} + + +ft_void_t FT800::ResetDLBuffer( ) +{ + dl_buff_wp = 0; +} + +/* Toggle PD_N pin of FT800 board for a power cycle*/ +ft_void_t FT800::Powercycle( ft_bool_t up) +{ + if (up) + { + //Toggle PD_N from low to high for power up switch + _pd = 0; + Sleep(20); + + _pd = 1; + Sleep(20); + }else + { + //Toggle PD_N from high to low for power down switch + _pd = 1; + Sleep(20); + + _pd = 0; + Sleep(20); + } +} + +ft_void_t FT800::WrMemFromFlash( ft_uint32_t addr,const ft_prog_uchar8_t *buffer, ft_uint32_t length) +{ + //ft_uint32_t SizeTransfered = 0; + + StartTransfer( FT_GPU_WRITE,addr); + + while (length--) { + Transfer8( ft_pgm_read_byte_near(buffer)); + buffer++; + } + + EndTransfer( ); +} + +ft_void_t FT800::WrMem( ft_uint32_t addr,const ft_uint8_t *buffer, ft_uint32_t length) +{ + //ft_uint32_t SizeTransfered = 0; + + StartTransfer( FT_GPU_WRITE,addr); + + while (length--) { + Transfer8( *buffer); + buffer++; + } + + EndTransfer( ); +} + + +ft_void_t FT800::RdMem( ft_uint32_t addr, ft_uint8_t *buffer, ft_uint32_t length) +{ + //ft_uint32_t SizeTransfered = 0; + + StartTransfer( FT_GPU_READ,addr); + + while (length--) { + *buffer = Transfer8( 0); + buffer++; + } + + EndTransfer( ); +} + +ft_int32_t FT800::Dec2Ascii(ft_char8_t *pSrc,ft_int32_t value) +{ + ft_int16_t Length; + ft_char8_t *pdst,charval; + ft_int32_t CurrVal = value,tmpval,i; + ft_char8_t tmparray[16],idx = 0; + + Length = strlen(pSrc); + pdst = pSrc + Length; + + if(0 == value) + { + *pdst++ = '0'; + *pdst++ = '\0'; + return 0; + } + + if(CurrVal < 0) + { + *pdst++ = '-'; + CurrVal = - CurrVal; + } + /* insert the value */ + while(CurrVal > 0){ + tmpval = CurrVal; + CurrVal /= 10; + tmpval = tmpval - CurrVal*10; + charval = '0' + tmpval; + tmparray[idx++] = charval; + } + + for(i=0;i<idx;i++) + { + *pdst++ = tmparray[idx - i - 1]; + } + *pdst++ = '\0'; + + return 0; +} + + +ft_void_t FT800::Sleep(ft_uint16_t ms) +{ + wait_ms(ms); +} + +ft_void_t FT800::Sound_ON(){ + Wr8( REG_GPIO, 0x02 | Rd8( REG_GPIO)); +} + +ft_void_t FT800::Sound_OFF(){ + Wr8( REG_GPIO, 0xFD & Rd8( REG_GPIO)); +} +