for Riverdi EVE-70
src/FT_GPU_Hal.cpp
- Committer:
- JackB
- Date:
- 2018-07-23
- Revision:
- 10:6a81aeca25e3
- Parent:
- 8:b5a41d1581ad
- Child:
- 11:2f11d40f0f9a
File content as of revision 10:6a81aeca25e3:
/* mbed Library for FTDI FT813 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" //Serial pc(USBTX, USBRX); #define SPI_SPEED_START 10000000 #define SPI_SPEED_AFTER 27000000 FT813::FT813(PinName mosi, PinName miso, PinName sck, PinName ss, PinName intr, PinName pd) : _spi(mosi, miso, sck), _ss(ss), _pd(pd), _f800_isr(InterruptIn(intr)) { _spi.format(8, 0); // 8 bit spi mode 0 _spi.frequency(SPI_SPEED_START); // start with 10 Mhz SPI clock _ss = 1; // cs high _pd = 1; // PD high Bootup(); _address = 0; _bitmap_count = 0; _bitmapCount = 0; _bitmapAddress = 0; } ft_bool_t FT813::Bootup(void) { // terminal.printf("Bootup() entered\r\n"); Open(); BootupConfig(); return(1); } ft_void_t FT813::BootupConfig(void) { ft_uint8_t chipid; /* Do a power cycle for safer side */ Powercycle(FT_TRUE); /* 7/8/16: Curt added the sleep delay below... */ // Sleep(30); /* Set the clk to external clock */ HostCommand(FT_GPU_EXTERNAL_OSC); Sleep(10); /* Access address 0 to wake up the FT813 */ HostCommand(FT_GPU_ACTIVE_M); Sleep(500); /* Switch PLL output to 48MHz */ HostCommand(FT_GPU_PLL_48M); Sleep(10); /* Do a core reset for safer side */ HostCommand(FT_GPU_CORE_RESET); Sleep(500); //Read Register ID to check if FT813 is ready. chipid = Rd8(REG_ID); // chipid = Rd8(0x0C0000); // printf("ID1: 0x%08X\n", chipid); while(chipid != 0x7C) // wait(1); // printf("ID2: 0x%08X\n", chipid); // Speed up // _spi.frequency(50000000); // 30 Mhz SPI clock DC _spi.frequency(SPI_SPEED_AFTER); // 20 Mhz SPI clock DC // _spi.frequency(12000000); // 12 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, 0); DispPCLK = my_DispPCLK; Wr8(REG_PCLK, DispPCLK); // After this display is visible on the LCD Wr16(REG_PWM_HZ, 10000); //#ifdef Inv_Backlite // turn on backlite // Wr16(REG_PWM_DUTY, 0); //#else Wr16(REG_PWM_DUTY, 255); // Brightness 127 //#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,2400); Wr16(REG_TOUCH_RZTHRESH, 0xFFFF); } /* API to initialize the SPI interface */ ft_bool_t FT813::Init() { // This is done in the constructor return 1; } ft_bool_t FT813::Open() { cmd_fifo_wp = dl_buff_wp = 0; status = OPENED; return 1; } ft_void_t FT813::Close() { status = CLOSED; } ft_void_t FT813::DeInit() { } /*The APIs for reading/writing transfer continuously only with small buffer system*/ ft_void_t FT813::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 FT813::StartCmdTransfer(FT_GPU_TRANSFERDIR_T rw, ft_uint16_t count) { StartTransfer(rw, cmd_fifo_wp + RAM_CMD); } ft_uint8_t FT813::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 FT813::Transfer8(ft_uint8_t value) { return _spi.write(value); } ft_uint16_t FT813::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 FT813::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 FT813::EndTransfer() { _ss = 1; status = OPENED; } ft_uint8_t FT813::Rd8(ft_uint32_t addr) { ft_uint8_t value; StartTransfer(FT_GPU_READ, addr); value = Transfer8(0); EndTransfer(); return value; } ft_uint16_t FT813::Rd16(ft_uint32_t addr) { ft_uint16_t value; StartTransfer(FT_GPU_READ, addr); value = Transfer16(0); EndTransfer(); return value; } ft_uint32_t FT813::Rd32(ft_uint32_t addr) { ft_uint32_t value; StartTransfer(FT_GPU_READ, addr); value = Transfer32(0); EndTransfer(); return value; } ft_void_t FT813::Wr8(ft_uint32_t addr, ft_uint8_t v) { // StartTransfer(FT_GPU_WRITE, addr); // if (FT_GPU_READ == rw) { // if (FT_GPU_READ == FT_GPU_WRITE) // _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; // } // Transfer8(v); _spi.write(v); // EndTransfer(); _ss = 1; status = OPENED; } ft_void_t FT813::Wr16(ft_uint32_t addr, ft_uint16_t v) { StartTransfer(FT_GPU_WRITE, addr); Transfer16(v); EndTransfer(); } ft_void_t FT813::Wr32(ft_uint32_t addr, ft_uint32_t v) { StartTransfer(FT_GPU_WRITE, addr); Transfer32(v); EndTransfer(); } ft_void_t FT813::HostCommand(ft_uint8_t cmd) { _ss = 0; _spi.write(cmd); _spi.write(0); _spi.write(0); _ss = 1; } ft_void_t FT813::ClockSelect(FT_GPU_PLL_SOURCE_T pllsource) { HostCommand(pllsource); } ft_void_t FT813::PLL_FreqSelect(FT_GPU_PLL_FREQ_T freq) { HostCommand(freq); } ft_void_t FT813::PowerModeSwitch(FT_GPU_POWER_MODE_T pwrmode) { HostCommand(pwrmode); } ft_void_t FT813::CoreReset() { HostCommand(0x68); } ft_void_t FT813::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 FT813::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 FT813::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); _spi.write(*buffer); buffer++; SizeTransfered++; } length = SizeTransfered; EndTransfer(); Updatecmdfifo(length); WaitCmdfifo_empty(); count -= length; } while (count > 0); } ft_void_t FT813::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 FT813::CheckCmdBuffer(ft_uint16_t count) { ft_uint16_t getfreespace; do { getfreespace = fifo_Freespace(); } while(getfreespace < count); } ft_void_t FT813::WaitCmdfifo_empty() { while(Rd16(REG_CMD_READ) != Rd16(REG_CMD_WRITE)); cmd_fifo_wp = Rd16(REG_CMD_WRITE); } ft_void_t FT813::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 FT813::ResetCmdFifo() { cmd_fifo_wp = 0; } ft_void_t FT813::WrCmd32(ft_uint32_t cmd) { CheckCmdBuffer(sizeof(cmd)); Wr32(RAM_CMD + cmd_fifo_wp, cmd); Updatecmdfifo(sizeof(cmd)); } ft_void_t FT813::ResetDLBuffer() { dl_buff_wp = 0; } /* Toggle PD_N pin of FT813 board for a power cycle*/ ft_void_t FT813::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 FT813::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 FT813::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 FT813::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 FT813::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 FT813::Sleep(ft_uint16_t ms) { wait_ms(ms); } ft_void_t FT813::Sound_ON() { Wr8(REG_GPIO, 0x02 | Rd8(REG_GPIO)); } ft_void_t FT813::Sound_OFF() { Wr8(REG_GPIO, 0xFD & Rd8(REG_GPIO)); }