Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Chromatograph_Mobile
src/FT_GPU_Hal.cpp
- Committer:
- nikmaos
- Date:
- 2020-08-08
- Revision:
- 12:f0980f7a75ae
- Parent:
- 11:2f11d40f0f9a
- Child:
- 13:5959af2ac87a
File content as of revision 12:f0980f7a75ae:
/* 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);
//Serial pc(SERIAL_TX,SERIAL_RX,115200);
#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
_IsOn=Bootup();
_address = 0;
_bitmap_count = 0;
_bitmapCount = 0;
_bitmapAddress = 0;
}
ft_bool_t FT813::Bootup(void)
{
//printf("Bootup() entered\r\n");//temp
Open();
return BootupConfig();
}
ft_bool_t FT813::IsOn(void)
{
return FT813::_IsOn;
}
char 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_INTERNAL_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);
//pc.printf("ID1: 0x%08X\n", chipid);//temp
//Если дисплей не отвечает то прервать инициализацию
char sec=0;
while(chipid != 0x7C) //раскомментить как заработает
{
wait_ms(100);
sec++;
if (sec>5)
{
printf("ERR!: Display is not connected\r\n");
return 0;
}
}
//tmp
//printf("ID2: 0x%08X\n", chipid);//tmp
// 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, 1); //поменяно для Riverdi 0 на 1
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, 1800); //поменяно с 0xFFFF на 1800
return 1; //дисплей включен и настроен
}
/* 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));
}