Processeur graphique FT800Q

Description

Graphical Processing Unit (GPU) FT800Q de FTDI : j'ai utilisé ce processeur graphique dans un montage afin de simplifier la programmation. En effet, ce circuit intégré possède des fonctions de type « widgets » qui facilitent grandement la programmation de l'interface graphique.

Principe : le processeur hôte communique avec le FT800Q via le bus SPI.

La première consiste à écrire directement les commandes de la liste d'affichage dans le RAM_DL (Display List RAM).

La deuxième consiste à écrire une série de commandes du coprocesseur ou de commandes de liste d'affichage dans le RAM_CMD (Command FIFO). Le coprocesseur crée ensuite la liste d'affichage dans le RAM_DL à partir des commandes qui lui sont transmises via le FIFO (RAM_CMD). Cette méthode facilite la combinaison d'objets graphiques (lignes, etc.) et de widgets (curseurs, etc.) sur un même écran.
image principale

Remarque: bien qu'il soit théoriquement possible de mélanger les deux méthodes lors de la création d'une nouvelle liste d'affichage (écran), il est recommandé d'utiliser une seule méthode pour un écran donné. En effet, le RAM_DL serait alors écrit à la fois par le MCU et par le coprocesseur au sein du FT800.

FIFO RAM_CMD

Commande de traitement FIFO

Lorsque REG_CMD_READ = REG_CMD_WRITE, le coprocesseur a exécuté toutes les commandes présentes dans le FIFO de commandes.

ft800q.cpp

		do {
		HAL_SPI_CSLow();
		HAL_SPI_SendAddressRD(REG_CMD_WRITE);   //
		cmdBufferWr = FT800_SPI_Read32();       //
		HAL_SPI_CSHigh();
		
HAL_SPI_CSLow(); HAL_SPI_SendAddressRD(REG_CMD_READ); // cmdBufferRd = FT800_SPI_Read32(); // HAL_SPI_CSHigh(); } while(cmdBufferWr != cmdBufferRd);

Étape 2

Le FT800 utilise un tampon circulaire de type FIFO pour stocker sa liste de commandes. Lorsqu'une nouvelle liste doit être créée, le MCU écrit les commandes à partir du prochain emplacement disponible, c'est-à-dire à la valeur actuelle de REG_CMD_WRITE. Le code ci-dessus attend que toutes les commandes aient été exécutées. La valeur de REG_CMD_WRITE est donc copiée dans une variable qui servira d'index de départ.

CMD_Offset = cmdBufferWr; // Obtenir la valeur actuelle du pointeur CMD_WRITE

Étape 3

La première commande de la liste peut maintenant être écrite dans le FIFO de commandes (RAM_CMD). La fonction SendAddressWR est utilisée pour envoyer la commande à l'adresse contenue dans cmdBufferWr.

Dans ce cas, la commande est DL_START (CMD_DLSTART). Les commandes destinées au FT800 sont toujours constituées de multiples de 4 octets. La ligne Chip_Select est ensuite désactivée, marquant ainsi la fin de cette commande.

Cette opération a écrit quatre octets dans le FIFO. Une liste de commandes étant généralement composée de nombreuses commandes, le MCU doit maintenant mettre à jour sa propre valeur de décalage dans la variable cmdBufferWr afin de connaître la position à laquelle écrire la commande suivante.

La fonction FT800_IncCMDOffset

Dans la plupart des cas, cette fonction ajoute simplement la longueur de la dernière commande au décalage précédent. Elle gère également le cas où l'index atteint 4095 et doit revenir à 0, en raison de la nature circulaire du FIFO.

ft800q.cpp

		uint32_t ft800q::inc_cmd_Offset(uint32_t currentOffset, uint8_t commandSize)
		{
			uint16_t 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
		}
		
La méthode ci-dessus est proposée dans le document « Programmer's Guide FT800 » de FTDI. Personnellement, je préfère toutefois utiliser une méthode différente :
ft800q.cpp

 	/*** CMD Functions ***************************************/
	uint8_t ft800q::cmd_execute(uint32_t data)
	{
		uint32_t cmdBufferRd = 0;
		uint32_t cmdBufferWr = 0;
    	cmdBufferRd = HOST_MEM_RD32(REG_CMD_READ);
    	cmdBufferWr = HOST_MEM_RD32(REG_CMD_WRITE);
    	uint32_t cmdBufferDiff = cmdBufferWr - cmdBufferRd;
    	if( (4096 - cmdBufferDiff) > 4)
    	{
        	HOST_MEM_WR32(RAM_CMD + cmdBufferWr, data);
        	HOST_MEM_WR32(REG_CMD_WRITE, cmdBufferWr + 4);
        	return 1;
    	}
    	return 0;
	}

	uint8_t ft800q::cmd(uint32_t data)
	{
		uint8_t tryCount = 255;
		for(tryCount = 255; tryCount > 0; --tryCount)
		{
			if(cmd_execute(data)) { return 1; }
		}
	return 0;
	}
	

Fonctionnement de la commande FIFO

La commande cmd(CMD_DLSTART) fait appel à la fonction cmd_execute. Celle-ci effectue jusqu'à 255 tentatives tant qu'elle ne retourne pas la valeur 1, indiquant que la commande a pu être exécutée.

La fonction cmd_execute retourne 0 tant que les deux registres ne permettent pas l'écriture d'une nouvelle commande. Dès que l'espace nécessaire est disponible, la commande est écrite dans la mémoire RAM_CMD.

Le registre REG_CMD_WRITE est ensuite incrémenté de 4 octets afin de pointer vers l'emplacement suivant du FIFO.

À retenir : chaque commande occupe un emplacement dans le FIFO. Le pointeur d'écriture avance de 4 octets après chaque écriture.

Chaque appel à la fonction cmd déclenche également la procédure HOST_MEM_WR32. Celle-ci permet d'écrire la commande dans le FIFO et de mettre à jour l'adresse utilisée pour l'écriture dans le registre REG_MEM_CMD.

ft800q.cpp

 	/* ------------------------------------------------------------------------------------------ */
	/* Demo Screen */
	void ft800q::lcd_start_screen(uint8_t button)
	{
		cmd(CMD_DLSTART);
		cmd(CLEAR_COLOR_RGB(0,0,0));
		cmd(CLEAR(1,1,1));
		cmd_gradient(0,0,0xA1E1FF, 0,250,0x000080);
		cmd_text(10,220, 20,0, "Designed by: Herve Fankhauser");
		cmd_text(300,200, 20,OPT_RIGHTX, "zfphfr/myqnapcould.com/hfe");
		cmd(COLOR_RGB(0xDE,0x00,0x08));
		cmd_text(140,40, 31,OPT_CENTERX, "FT800 Demo");
		cmd(COLOR_RGB(255,255,255));
		cmd(TAG(1));

		if(!button)
		{
			cmd_fgcolor(0x228B22);
			cmd_button(50,150, 220,48, 28,0, "Tap to Continue");
		}
		else
		{
			cmd_fgcolor(0x0A520A);
			cmd_button(50,150, 220,48, 28,OPT_FLAT, "Tap to Continue");
		}
		
		cmd(DISPLAY());
		cmd(CMD_SWAP);
	}
	

🔒 Fichiers du projet — Membres

Code C++ pour le ft800q.

💻

Code source

Code source C du microcontrôleur et fichiers associés.

🔒 Connexion nécessaire
image resultat
🔒 Accès réservé aux membres
Connectez-vous pour accéder aux fichiers du projet.
Se connecter