This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/EK-TM4C1294XL: getting started FT800 with TM4C1294XL

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

  • Hello Angel

    The SSI controller on TM4C devices require that the RX FIFO be cleared whenever a byte is written.

    Since the protoype of the ft800mem_Write8 r Write16 command is not described in your code, it would be tough to decipher the action it is performing and the implication of the same for the TM4C device.
  • Hello many thanks for your early response

    with my code I get to turn on the DisplayLCD but it only shows full brightness and as I mentioned before when I try to read on any register I had to call twice any read function (why? I don't understand)

    Regards!

    these is my read and write functions that I have used

    Write functions:

    void ft800cmd_Write(unsigned char ftCommand)
    {
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0);                     // Set chip select low
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);
    
        // Initialize the data to send.
        SSIDataPut(SSI0_BASE, ftCommand);                                                     // Send command
        SSIDataPut(SSI0_BASE, 0x00);                                                                 // Send first filler byte
        SSIDataPut(SSI0_BASE, 0x00);                                                                 // Send second filler byte
    
        while(SSIBusy(SSI0_BASE));
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS);    // Set chip select high
    }
    
    void ft800mem_Write8(unsigned long ftAddress, unsigned char ftData8)
    {
        unsigned char cTempAddr[3];                                                                    // FT800 Memory Address
    
        cTempAddr[2] = (char) (ftAddress >> 16) | MEM_WRITE;                    // Compose the command and address to send
        cTempAddr[1] = (char) (ftAddress >> 8);                                                  // middle byte
        cTempAddr[0] = (char) (ftAddress);                                                           // low byte
    
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0);                   // Set chip select low
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);
    
        for (i = 2; i >= 0; i--)
        {
            SSIDataPut(SSI0_BASE, cTempAddr[i]);                                             // Send Memory Write plus high address byte
        }
    
        for (j = 0; j >= 0; j--)
        {
            SSIDataPut(SSI0_BASE, ftData8);                                                       // Send data byte
        }
    
        while(SSIBusy(SSI0_BASE));
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS);    // Set chip select high
    }
    
    void ft800mem_Write16(unsigned long ftAddress, unsigned int ftData16)
    {
        unsigned char cTempAddr[3];                                                                           // FT800 Memory Address
        unsigned char cTempData[2];                                                                           // 16-bit data to write
    
        cTempAddr[2] = (char) (ftAddress >> 16) | MEM_WRITE;                           // Compose the command and address to send
        cTempAddr[1] = (char) (ftAddress >> 8);                                                        // middle byte
        cTempAddr[0] = (char) (ftAddress);                                                                 // low byte
    
        cTempData[1] = (char) (ftData16 >> 8);                                                         // Compose data to be sent - high byte
        cTempData[0] = (char) (ftData16);                                                                  // low byte
    
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0);                         // Set chip select low
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);
    
        for (i = 2; i >= 0; i--)
        {
            SSIDataPut(SSI0_BASE, cTempAddr[i]);                                                // Send Memory Write plus high address byte
        }
    
        for (j = 1; j >= 0; j--)                                                                                          // Start with least significant byte
        {
            SSIDataPut(SSI0_BASE, cTempData[j]);                                               // Send data byte
        }
    
        while(SSIBusy(SSI0_BASE));
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS);    // Set chip select high
    }
    
    void ft800mem_Write32(unsigned long ftAddress, unsigned long ftData32)
    {
        unsigned char cTempAddr[3];                                                                          // FT800 Memory Address
        unsigned char cTempData[4];                                                                         // 32-bit data to write
    
        cTempAddr[2] = (char) (ftAddress >> 16) | MEM_WRITE;        // Compose the command and address to send
        cTempAddr[1] = (char) (ftAddress >> 8);                     // middle byte
        cTempAddr[0] = (char) (ftAddress);                          // low byte
    
        cTempData[3] = (char) (ftData32 >> 24);                     // Compose data to be sent - high byte
        cTempData[2] = (char) (ftData32 >> 16);                     //
        cTempData[1] = (char) (ftData32 >> 8);                      //
        cTempData[0] = (char) (ftData32);                           // low byte
    
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0);              // Set chip select low
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);
    
        for (i = 2; i >= 0; i--)
        {
            SSIDataPut(SSI0_BASE, cTempAddr[i]);                    // Send Memory Write plus high address byte
        }
    
        for (j = 3; j >= 0; j--)                                    // Start with least significant byte
        {
            SSIDataPut(SSI0_BASE, cTempData[j]);                    // Send data byte
        }
    
        while(SSIBusy(SSI0_BASE));
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS);    // Set chip select high
    }

    Read functions:

    unsigned char ft800mem_Read8(unsigned long ftAddress)
    {
        unsigned char ftData8 = 0;                                      // Place-holder for 8-bits being read
        unsigned char cTempAddr[3];                                 // FT800 Memory Address
        unsigned char cZeroFill = ZERO;
    
        cTempAddr[2] = (char) (ftAddress >> 16) | MEM_READ;         // Compose the command and address to send
        cTempAddr[1] = (char) (ftAddress >> 8);                     // middle byte
        cTempAddr[0] = (char) (ftAddress);                          // low byte
    
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0);              // Set chip select low
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);
    
        for (i = 2; i >= 0; i--)
        {
            SSIDataPut(SSI0_BASE, cTempAddr[i]);                    // Send Memory Write plus high address byte
        }
    
        SSIDataPut(SSI0_BASE, cZeroFill);                           // Send dummy byte
    
        for (j = 0; j < sizeof(ftData8); j++)                       // Start with least significant byte
        {
            SSIDataGet(SSI0_BASE, &ftData8);                        // Receive data byte
        }
    
        while(SSIBusy(SSI0_BASE));
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS);    // Set chip select high
    
      return ftData8;                                               // Return 8-bits
    }
    
    unsigned int ft800mem_Read16(unsigned long ftAddress)
    {
        unsigned int ftData16 = 0;                                      // 16-bits to return
        unsigned char cTempAddr[3];                                 // FT800 Memory Address
        unsigned char cTempData[2];                                 // Place-holder for 16-bits being read
        unsigned char cZeroFill = ZERO;
    
        cTempAddr[2] = (char) (ftAddress >> 16) | MEM_READ;         // Compose the command and address to send
        cTempAddr[1] = (char) (ftAddress >> 8);                     // middle byte
        cTempAddr[0] = (char) (ftAddress);                          // low byte
    
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0);              // Set chip select low
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);
    
      for (i = 2; i >= 0; i--)
        {
          SSIDataPut(SSI0_BASE, cTempAddr[i]);                      // Send Memory Write plus high address byte
        }
    
        SSIDataPut(SSI0_BASE, cZeroFill);                           // Send dummy byte
    
        for (j = 0; j < sizeof(cTempData); j++)                     // Start with least significant byte
        {
            SSIDataGetNonBlocking(SSI0_BASE, &cTempData[j]);        // Receive data byte
        }
    
        while(SSIBusy(SSI0_BASE));
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS);    // Set chip select high
    
        ftData16 = (cTempData[1]<< 8) |                             // Compose value to return - high byte
                           (cTempData[0]);                          // low byte
    
      return ftData16;                                          // Return 16-bits
    }
    
    unsigned long ft800mem_Read32(unsigned long ftAddress)
    {
        unsigned long ftData32 = 0;                                     // 32-bits to return
        unsigned char cTempAddr[3];                                 // FT800 Memory Address
        unsigned char cTempData[4];                                 // Place holder for 32-bits being read
        unsigned char cZeroFill= ZERO;                              // Dummy byte
    
        cTempAddr[2] = (char) (ftAddress >> 16) | MEM_READ;         // Compose the command and address to send
        cTempAddr[1] = (char) (ftAddress >> 8);                     // middle byte
        cTempAddr[0] = (char) (ftAddress);                          // low byte
    
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0);              // Set chip select low
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);
    
        for (i = 2; i >= 0; i--)
        {
            SSIDataPut(SSI0_BASE, cTempAddr[i]);                    // Send Memory Write plus high address byte
        }
    
        SSIDataPut(SSI0_BASE, cZeroFill);                           // Send dummy byte
    
        for (j = 0; j < sizeof(cTempData); j++)                     // Start with least significatn byte
        {
            SSIDataGetNonBlocking(SSI0_BASE, &cTempData[j]);        // Receive data byte
        }
    
        while(SSIBusy(SSI0_BASE));
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS);    // Set chip select high
    
        ftData32 = (cTempData[3]<< 24) |                            // Compose value to return - high byte
                             (cTempData[2]<< 16) |
                             (cTempData[1]<< 8) |
                             (cTempData[0]);                        // Low byte
    
      return ftData32;                                              // Return 32-bits
    }

    This function increase the command pointer:

    unsigned int incCMDOffset(unsigned int currentOffset, unsigned char commandSize)
    {
        unsigned int newOffset;                                      // Used to hold new offset
        newOffset = currentOffset + commandSize;                     // Calculate new offset
        if(newOffset > 4095)                                         // If new offset past boundary...
        {
            newOffset = (newOffset - 4096);                          // ... roll over pointer
        }
        return newOffset;                                            // Return new offset
    }

    And this is the SSI init function:

    void ConfigureSSI(void)
    {
         MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
         MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
         MAP_GPIOPinConfigure(GPIO_PA2_SSI0CLK);
         //MAP_GPIOPinConfigure(GPIO_PA3_SSI0FSS);
         MAP_GPIOPinConfigure(GPIO_PA4_SSI0XDAT0); //Tx
         MAP_GPIOPinConfigure(GPIO_PA5_SSI0XDAT1); //RX
         MAP_GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_2);
    
         MAP_SSIConfigSetExpClk(SSI0_BASE, 120000000, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 10000000, 8);
         
         MAP_SSIEnable(SSI0_BASE);
    }
  • Hello Angelo,

    Thanks for the code post. The issue as I see is that when a read operation is done, it is a non-blocking read which is being done without a write and flush operation.

    unsigned char ft800mem_Read8(unsigned long ftAddress)
    {
    unsigned char ftData8 = 0; // Place-holder for 8-bits being read
    unsigned char cTempAddr[3]; // FT800 Memory Address
    unsigned char cZeroFill = ZERO;

    cTempAddr[2] = (char) (ftAddress >> 16) | MEM_READ; // Compose the command and address to send
    cTempAddr[1] = (char) (ftAddress >> 8); // middle byte
    cTempAddr[0] = (char) (ftAddress); // low byte

    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0); // Set chip select low
    while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);

    for (i = 2; i >= 0; i--)
    {
    SSIDataPut(SSI0_BASE, cTempAddr[i]); // Send Memory Write plus high address byte
    }

    SSIDataPut(SSI0_BASE, cZeroFill); // Send dummy byte

    for (j = 0; j < sizeof(ftData8); j++) // Start with least significant byte
    {
    SSIDataGet(SSI0_BASE, &ftData8); // Receive data byte
    }

    while(SSIBusy(SSI0_BASE));
    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS); // Set chip select high

    return ftData8;
    }

    Must be

    unsigned char ft800mem_Read8(unsigned long ftAddress)
    {
    unsigned char ftData8 = 0; // Place-holder for 8-bits being read
    unsigned char cTempAddr[3]; // FT800 Memory Address
    unsigned char cZeroFill = ZERO;

    cTempAddr[2] = (char) (ftAddress >> 16) | MEM_READ; // Compose the command and address to send
    cTempAddr[1] = (char) (ftAddress >> 8); // middle byte
    cTempAddr[0] = (char) (ftAddress); // low byte

    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0); // Set chip select low
    while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);

    for (i = 2; i >= 0; i--)
    {
    SSIDataPut(SSI0_BASE, cTempAddr[i]); // Send Memory Write plus high address byte
    }
    while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);

    SSIDataPut(SSI0_BASE, cZeroFill); // Send dummy byte

    for (j = 0; j < sizeof(ftData8); j++) // Start with least significant byte
    {
    SSIDataGet(SSI0_BASE, &ftData8); // Receive data byte
    }

    while(SSIBusy(SSI0_BASE));
    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS); // Set chip select high

    return ftData8;
    }
  • Hello Amit

    when I read after of write (Attached the codes test), I don't get data. But I saw on the oscilloscope that the signal RX is delayed I mean that the TF800 gave me the bytes of the previous ask.

    e.g. If I send the 'ROM_CHIPID' address it has to give me '0x08' but it gives me '0x00' and when I send again the 'ROM_CHIPID' address it gives me  the correct response '0x08' and if after I send the 'REG_ID' address it has to give me '0x7C' but it gives me '0x08' and when I send again the 'REG_ID' address it gives me the correct response '0x7C'. 

    I guess that the trouble is in my MAP_SSIConfigSetExpClk() settings but I don't understand what SSI clock must have. In the datasheet  I don't see those specifications.

    can you tell me a sugestion?

    Regards.

    1st attempt.

    unsigned char ft800mem_Read8(unsigned long ftAddress)
    {
        unsigned char ftData8;                                      // Place-holder for 8-bits being read
        unsigned char cTempAddr[3];                                 // FT800 Memory Address
        unsigned char cZeroFill = ZERO;
    
        cTempAddr[2] = (char) (ftAddress >> 16) | MEM_READ;         // Compose the command and address to send
        cTempAddr[1] = (char) (ftAddress >> 8);                     // middle byte
        cTempAddr[0] = (char) (ftAddress);                          // low byte
    
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0);              // Set chip select low
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);
    
        for (i = 2; i >= 0; i--)
        {
            SSIDataPut(SSI0_BASE, cTempAddr[i]);                    // Send Memory Write plus high address byte
        }
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);    // flush operation
        SSIDataPut(SSI0_BASE, cZeroFill);                           // Send dummy byte
        
        for (j = 0; j < sizeof(ftData8); j++)                       // Start with least significant byte
        {
            SSIDataGet(SSI0_BASE, &ftData8);                        // Receive data byte
        }
    
        while(SSIBusy(SSI0_BASE));
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS);    // Set chip select high
    
      return ftData8;                                               // Return 8-bits
    }

    2nd attempt.

    unsigned char ft800mem_Read8(unsigned long ftAddress)
    {
        unsigned char ftData8 = 0;                                  // Place-holder for 8-bits being read
        unsigned char cTempAddr[3];                                 // FT800 Memory Address
        unsigned char cZeroFill = ZERO;
    
        cTempAddr[2] = (char) (ftAddress >> 16) | MEM_READ;         // Compose the command and address to send
        cTempAddr[1] = (char) (ftAddress >> 8);                     // middle byte
        cTempAddr[0] = (char) (ftAddress);                          // low byte
    
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, 0);              // Set chip select low
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx) != 0);
    
        SSIDataPut(SSI0_BASE, cTempAddr[2]);
        SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx);    //flush operation
        SSIDataPut(SSI0_BASE, cTempAddr[1]);
        SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx);   //flush operation
        SSIDataPut(SSI0_BASE, cTempAddr[0]);                    // Send Memory Write plus high address byte
        SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx);   //flush operation
    
        SSIDataPut(SSI0_BASE, cZeroFill);                           // Send dummy byte
        SSIDataGet(SSI0_BASE, &ftData8);                        // Receive data byte
    
        while(SSIBusy(SSI0_BASE));
        GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_CS, GPIO_PIN_CS);    // Set chip select high
    
      return ftData8;                                               // Return 8-bits
    }

    I hope that I have explained well.

  • Hello Angel

    Please use SSIDataGet instead of SSIDataGetNonBlocking for flush operation during an active transaction where SSIDataPut is called.
  • Hello Amit

    Sorry to answer until now. I used SSIDataGet instead of SSIDataGetNonBlocking and I got the same answer.

    I have a question. How can I change the LBS and MBS parameters?


    Regards
  • Hello Angel

    Do you mean MSB and LSB? If yes, then it cannot be changed.
  • Hi,

    Reading the ARM application note specified by you in the first post:

    a) There is specified the SSI setting: COPL=0, CPHA=1; please see the SSI driverlib code, there are all info needed to set correctly the SPI module.

    b) Same document specify the sending order: least significant byte first. Seems you send it most significant byte first, your for loop should start from i=0, not 2

    c) SPI should send MSB first, aka most significant  bit first.

  • Yes I mean MSB and LSB.
  • Hello Angel

    No. MSB and LSB cannot be swapped.
  • Hello

    Many thanks for your early answers.

    I have been a little confused with the setting: COPL=0, CPHA=1 (it is mode 1) and the FT800 datasheet specified the SSI setting must be COPL=0, CPHA=0 (it is mode 0).
    And yes you have reason petrei the SPI should send MSB first but I would like know How can I change the LSB and MSB parameters in the SSI module.

    I think in those settings are the trouble.
    (comment: I am practicing my english too, if I have any bad expression please tell me)

    Regards
  • Hello

    Many thanks for your early answers.

    I have been a little confused with the setting: COPL=0, CPHA=1 (it is mode 1) and the FT800 datasheet specified the SSI setting must be COPL=0, CPHA=0 (it is mode 0).
    And yes you have reason petrei the SPI should send MSB first.

    I think in those settings are the trouble.
    (comment: I am practicing my english too, if I have any bad expression please tell me)

    Regards
  • Hello

    Many thanks for your early answers.

    I have been a little confused with the setting: COPL=0, CPHA=1 (it is mode 1) and the FT800 datasheet specified the SSI setting must be COPL=0, CPHA=0 (it is mode 0).

    And yes you have reason petrei the SPI should send MSB first.

    I think in those settings are the trouble.

    (comment: I am practicing my english too, if I have any bad expression please tell me)

    Regards

  • Hello Angel

    I would then suggest making the change for the correct operational mode. However, that should not be the cause as the entire transaction is shifted by one byte. I do believe it is a missing SSI RXFIFO data flush. To double check, connect a scope probe to CS, CLK, MISO and MOSI and check what the transaction on the bus and the code execution read of the data at that particular instance shows.
  • Hello Amit

    I was reading about SSI configuration and I made some changes in my funtions. yes I had a wrong in the functions. Now I'm able to write graphics on the LCDDisplay througth the FT800 drive but I still have Issues reading, for that reason I opened other post about the read with SSI port on FT800 drive.

    this is the link: e2e.ti.com/.../566770

    thank you

    Angel Nino
  • Hello Angel

    And I have responded to the same.... Advanced mode usage is different from the Legacy mode usage. We would use the new post to correspond on the same.