Part Number: EK-TM4C1294XL
Tool/software: Code Composer Studio
Hello
I am try to put some graphics on my DisplayLCD and I use the TM4C1294XL Launchpad, I have had some throubles when I try to read the SPI data
e.g. when I try to read the ID I called twice the function 'ft800mem_Read8(REG_ID)' becouse the first value that I get is incorrect and the correct value I get it in the second called.
I used the SSIDataGet(uint32_t ui32Base, uint32_t *pui32Data) functio for read the values from FT800.
I have been following the FT800_ARM_example_AN_312 from the FTDI oficial page and the FT800 Series Programmer Guide.
excuse me my englis it's not my native language, I hope that you understand me
Regards!
- A. Angel
Attached my source code.
FT800 Series Programmer Guide = http://www.ftdichip.com/Support/Documents/ProgramGuides/FT800%20Programmers%20Guide.pdf
example_AN_312 = http://www.ftdichip.com/Support/Documents/AppNotes/AN_312%20FT800%20Example%20with%20ARM.pdf
DisplayLCD = http://www.4dsystems.com.au/productpages/4DLCD-FT843/downloads/FT843-4.3-Display_datasheet_R_1_2.pdf
TivaWare Peripheral Driver Library User's Guide = http://www.ti.com/lit/ug/spmu298d/spmu298d.pdf
int main(void)
{
int value = 0;
unsigned char ft800Gpio;
// Run from the PLL at 120 MHz. g_ui32SysClock = 120000000.
g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480), 120000000);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
GPIOPinTypeGPIOInput(GPIO_PORTJ_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); //enable pin for SW_1 and pull_up
GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); //enable pin for SW_1 and pull_up
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
GPIOPinTypeGPIOInput(GPIO_PORTN_BASE, GPIO_PIN_INT);
GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_PD | GPIO_PIN_CS | GPIO_PIN_1 | GPIO_PIN_0); //enable pines for LED_2 and LED_1
ConfigureUART();
UARTprintf("*** UART_0 done ***\n");
ConfigureSSI();
UARTprintf("*** SSI_0 done ***\n");
//Display init_sequence
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_PD, GPIO_PIN_PD); // Initial state of PD_N - high
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS); // Initial state of SPI CS - high
MAP_SysCtlDelay((120000000 * 0.02) / 3);
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_PD, 0); // Reset FT800
MAP_SysCtlDelay((120000000 * 0.02) / 3);
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_PD, GPIO_PIN_PD); // FT800 is awake
MAP_SysCtlDelay((120000000 * 0.02) / 3);
ft800cmd_Write(FT800_ACTIVE); // Start FT800
MAP_SysCtlDelay((120000000 * 0.001) / 3);
ft800cmd_Write(FT800_CLKEXT); // Set FT800 for external clock
MAP_SysCtlDelay((120000000 * 0.001) / 3);
ft800cmd_Write(FT800_CLK48M); // Set FT800 for 48MHz PLL
MAP_SysCtlDelay((120000000 * 0.001) / 3);
unsigned char ft_ID = ft800mem_Read8(REG_ID);
ft_ID = ft800mem_Read8(REG_ID);
while (ft_ID != 0x7C)
{
UARTprintf("The FT800 ID = 0x%x. Is incorrect\n", ft_ID);
while(1);
}
ft800mem_Write8(REG_PCLK, ZERO); // Set PCLK to zero - don't clock the LCD until later
ft800mem_Write8(REG_PWM_DUTY, ZERO); // Turn off back-light
// Initialize Display LCD_WQVGA
ft800mem_Write16(REG_HSIZE, 480); // active display width
ft800mem_Write16(REG_HCYCLE, 548); // total number of clocks per line, incl front/back porch
ft800mem_Write16(REG_HOFFSET, 43); // start of active line
ft800mem_Write16(REG_HSYNC0, 0); // start of horizontal sync pulse
ft800mem_Write16(REG_HSYNC1, 41); // end of horizontal sync pulse
ft800mem_Write16(REG_VSIZE, 272); // active display height
ft800mem_Write16(REG_VCYCLE, 292); // total number of lines per screen, incl-pre/post
ft800mem_Write16(REG_VOFFSET, 12); // start of active screen
ft800mem_Write16(REG_VSYNC0, 0); // start of vertical sync pulse
ft800mem_Write16(REG_VSYNC1, 10); // end of vertical sync pulse
ft800mem_Write8(REG_SWIZZLE, 0); // FT800 output to LCD - pin order
ft800mem_Write8(REG_PCLK_POL, 1); // LCD data is clocked in on this PCLK edge
// Configure Touch and Audio
ft800mem_Write8(REG_TOUCH_MODE, ZERO); // Disable touch
ft800mem_Write16(REG_TOUCH_RZTHRESH, ZERO); // Eliminate any false touches
ft800mem_Write8(REG_VOL_PB, ZERO); // turn recorded audio volume down
ft800mem_Write8(REG_VOL_SOUND, ZERO); // turn synthesizer volume down
ft800mem_Write16(REG_SOUND, 0x6000); // set synthesizer to mute
ft800mem_Write32(RAM_DL + 0, CLEAR_COLOR_RGB(0,0,0)); // Clear Color RGB
ft800mem_Write32(RAM_DL + 4, CLEAR(1,1,1)); // Clear 00100110 -----CST (C/S/T define which parameters to clear)
ft800mem_Write32(RAM_DL + 8, DISPLAY());
ft800mem_Write8(REG_DLSWAP, DLSWAP_FRAME);
ft800Gpio = ft800mem_Read8(REG_GPIO_DIR);
ft800mem_Write8(REG_GPIO_DIR, 0x80 | ft800Gpio);
UARTprintf("REG_GPIO_DIR = 0x%x\n",ft800Gpio);
ft800Gpio = ft800mem_Read8(REG_GPIO); // Read the FT800 GPIO register for a read/modify/write operation
ft800mem_Write8(REG_GPIO, 0x080 | ft800Gpio); // Enable the DISP signal to the LCD panel
UARTprintf("REG_GPIO = 0x%x\n",ft800Gpio);
ft800mem_Write8(REG_PCLK, 5); // Now start clocking data to the LCD panel
int duty;
for(duty = 0; duty <= 128; duty++)
{
ft800mem_Write8(REG_PWM_DUTY, duty); // Turn on backlight - ramp up slowly to full brighness
MAP_SysCtlDelay((120000000 * 0.02) / 3);
}
while(1)
{
// Wait for graphics processor to complete executing the current command list
// This happens when REG_CMD_READ matches REG_CMD_WRITE, indicating that all commands
// have been executed. The next commands get executed when REG_CMD_WRITE is updated again...
// then REG_CMD_READ again catches up to REG_CMD_WRITE
// This is a 4Kbyte ring buffer, so keep pointers within the 4K roll-over
do
{
cmdBufferRd = ft800memRead16(REG_CMD_READ); // Read the graphics processor read pointer
cmdBufferWr = ft800memRead16(REG_CMD_WRITE); // Read the graphics processor write pointer
}while (cmdBufferWr != cmdBufferRd); // Wait until the two registers match
cmdOffset = cmdBufferWr; // The new starting point the first location after the last command
if (color != WHITE) // If a red dot was just drawn (or first time through)...
color = WHITE; // change color to white
else // Otherwise...
color = RED; // change the color to red
ft800memWrite32(RAM_CMD + cmdOffset, (CMD_DLSTART)); // Start the display list
cmdOffset = incCMDOffset(cmdOffset, 4); // Update the command pointer
ft800memWrite32(RAM_CMD + cmdOffset, (DL_CLEAR_RGB | BLACK)); // Set the default clear color to black
cmdOffset = incCMDOffset(cmdOffset, 4); // Update the command pointer
ft800memWrite32(RAM_CMD + cmdOffset, (DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG));
// Clear the screen - this and the previous prevent artifacts between lists
// Attributes are the color, stencil and tag buffers
cmdOffset = incCMDOffset(cmdOffset, 4); // Update the command pointer
ft800memWrite32(RAM_CMD + cmdOffset, (DL_COLOR_RGB | color)); // Set the color of the following item(s) - toggle red/white from above
cmdOffset = incCMDOffset(cmdOffset, 4); // Update the command pointer
ft800memWrite32(RAM_CMD + cmdOffset, (DL_POINT_SIZE | point_size)); // Select the size of the dot to draw
cmdOffset = incCMDOffset(cmdOffset, 4); // Update the command pointer
ft800memWrite32(RAM_CMD + cmdOffset, (DL_BEGIN | FTPOINTS)); // Indicate to draw a point (dot)
cmdOffset = incCMDOffset(cmdOffset, 4); // Update the command pointer
ft800memWrite32(RAM_CMD + cmdOffset, (DL_VERTEX2F | (point_x << 15) | point_y));// Set the point center location
cmdOffset = incCMDOffset(cmdOffset, 4); // Update the command pointer
ft800memWrite32(RAM_CMD + cmdOffset, (DL_END)); // End the point
cmdOffset = incCMDOffset(cmdOffset, 4); // Update the command pointer
ft800memWrite32(RAM_CMD + cmdOffset, (DL_DISPLAY)); // Instruct the graphics processor to show the list
cmdOffset = incCMDOffset(cmdOffset, 4); // Update the command pointer
ft800memWrite32(RAM_CMD + cmdOffset, (CMD_SWAP)); // Make this list active
cmdOffset = incCMDOffset(cmdOffset, 4); // Update the command pointer
ft800memWrite16(REG_CMD_WRITE, (cmdOffset)); // Update the ring buffer pointer so the graphics processor starts executing
SysCtlDelay((120000000 * 0.5) / 3); // Wait a half-second to observe the changing color
if((GPIOPinRead(GPIO_PORTJ_BASE,GPIO_PIN_0) & GPIO_PIN_0) == 0)
{
SysCtlDelay((120000000 * 0.15) / 3);
if (value == 0)
{
char chipID = ft800mem_Read8(ROM_CHIPID); // <<<< here when I try to read any register, I need to call it twice
chipID = ft800mem_Read8(ROM_CHIPID); // <<<< I do not know, what is the problem in my function.
UARTprintf("ROM_CHIPID = 0x%x.\n", chipID); //show on serial port the CHIPID
value = 1;
}
}
else if((GPIOPinRead(GPIO_PORTJ_BASE,GPIO_PIN_1) & GPIO_PIN_1) == 0)
{
SysCtlDelay((120000000 * 0.15) / 3);
if (value == 0)
{
char man_ID = ft800mem_Read8(REG_ID);
man_ID = ft800mem_Read8(REG_ID);
UARTprintf("REG_ID = 0x%x.\t0x7C\n", man_ID);
value = 1;
}
}
else
{
value = 0;
}
}
}