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; } } }