Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 pushé pour l'init... j'ai nettoyé un peu au passage
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 @Epsylon3Merci pour le nettoyage... question : case U8G_DEV_MSG_PAGE_NEXT: for (uint16_t y = 0; y < 8; y++) { uint32_t k = 0; for (i = 0; i < (uint32_t)pb->width; i++) { const uint8_t b = *(((uint8_t *)pb->buf) + i); const uint16_t c = TEST(b, y) ? TFT_MARLINUI_COLOR : TFT_MARLINBG_COLOR; buffer[k++] = c; buffer[k++] = c; } for (k = 0; k < 2; k++) { #ifdef LCD_USE_DMA_FSMC LCD_IO_WriteSequence(buffer, 256); #else u8g_WriteSequence(u8g, dev, 128, (uint8_t*)buffer); u8g_WriteSequence(u8g, dev, 128, (uint8_t*)&(buffer[64])); u8g_WriteSequence(u8g, dev, 128, (uint8_t*)&(buffer[128])); u8g_WriteSequence(u8g, dev, 128, (uint8_t*)&(buffer[192])); #endif } Ne serait il pas possible d'eviter la boucle for (K=0, k<2.... avec un truc du genre : LCD_IO_WriteSequence(buffer, 3*256); Ca permet de lancer un seul gros transfert DMA au lieu de 3 petits? Je ne me souviens plus exactement de la raison du triple transfert...
Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 (modifié) non, le buffer est de 256 uint16_t (qu'on envoie 2 fois pour le zoom 2x) sinon un pixel sur 2 est alumé 2x2 = 4 pixels identiques mmm enfin c'est possible de faire un dma specifique pour envoyer 2x la meme chose, mais faut 2x la memoire buffer aussi apres: https://cdn-shop.adafruit.com/datasheets/ILI9341.pdf peut avoir des trucs utiles aussi, genre faire un carré rempli directement Modifié (le) Mai 6, 2019 par Epsylon3
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 (modifié) il y a 7 minutes, Epsylon3 a dit : non, le buffer est de 256 uint16_t (qu'on envoie 2 fois pour le zoom 2x) Dommage, car l'idee c'est de faire les transferts DMA les plus gros possibles, pour laisser le CPU faire autre chose. Et du coup, il faudrait en envoyer un maximum d'un seul coup... Deja, je pense que tu dois voir un beau changement avec le clear screen complet. Est il exact que pour passer de la page de surveillance, au menu, le clearscreen est utilise? Edit : En fait non.... On n'utilise en effet le clear screen qu'au debut. Modifié (le) Mai 6, 2019 par Hobi
Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 (modifié) yep... c'est utilisé et pt meme 2 fois pendant le démarrage.. j'ai testé le Multiple avec la taille/2 tiens le pdf a : Write Display Brightness (51h) je me demande si ca peut gerer le backlight aussi leur chip oui enfin on reinit a l'entrée du menu ce qui passe par la... c'est surtout la le benefice un peu visible Modifié (le) Mai 6, 2019 par Epsylon3
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 Pour gagner vraiment, il faut que le DMA tourne pendant que le CPU tourne. Faudrait regarder la doc du DMA, pour voir si il ne peut pas recommencer 2 fois le meme transfert tout seul. Si c'est le cas, on peut avoir toute la boucle de preparation : for (i = 0; i < (uint32_t)pb->width; i++) { const uint8_t b = *(((uint8_t *)pb->buf) + i); const uint16_t c = TEST(b, y) ? TFT_MARLINUI_COLOR : TFT_MARLINBG_COLOR; buffer[k++] = c; buffer[k++] = c; } en execution simultanee avec le transfert DMA complet. Faut voire si ca vaut le coup.
Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 tiens a propos de "l'init double"... je peux encore optimiser
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 Il faut enlever le test de sortie du DMA while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {}; dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); Et soit le placer avant de lancer une LCD_IO_WriteMultiple mais c'est pas très propre, mais c'est simple vu qu'on a un seul endroit, ou deux, ou cette procédure est appelée, ou bien utiliser un boolean global, qui est remis a 0 sur interruption de fin de transfert DMA. C'est un poil plus complique, et rajouter une interruption pour juste faire ca me parait pas forcement plus rapide.
Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 (modifié) yep enfin ca ne nous aide pas.... vu qu'on le fait 2x... par contre le dma en interne utilise peut etre deja de la ram... Il est peut etre possible de la réutiliser pour envoyer 2x le meme buffer ce double init m'intrigue.... je vais mettre un compteur pour voir si c'est pas fait 3 fois Modifié (le) Mai 6, 2019 par Epsylon3
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 il y a 1 minute, Epsylon3 a dit : yep enfin ca ne nous aide pas.... vu qu'on le fait 2x... par contre le dma en interne utilise peut etre deja de la ram... Il est peut etre possible de la réutiliser pour envoyer 2x le meme buffer Nous sommes d'accord.... Il faudrait ne pas avoir a le faire 2 fois, et laisser le DMA gerer la duplication.
Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 (modifié) ok, j'ai préparé le jeu de fonctions async. et fait encore qq optimisations hmm a propos du while ... while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {}; il faudrait pas ajouter un genre de "nop" pour liberer le SoC (permettre d'autres taches par ex.) et sinon : void dma_set_num_transfers(dma_dev *dev, dma_tube tube, uint16 num_transfers) Set the number of data transfers on a DMA tube. You may not call this function while the tube is enabled. Parameters dev - DMA device tube - Tube through which the transfer will occur. num_transfers - Number of DMA transactions to set. Modifié (le) Mai 6, 2019 par Epsylon3
Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 Non, mais ok, on peut simplement doubler le buffer en fait... et beaucoup simplifier le code de la ligne avec le Multiple
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 J allais tester le double buffer ce soir. Vas y! Je vais mesurer. Dans le genre on pourrait aussi mettre des icônes déjà a la bonne taille en rom, on a 350ko de dispo. Comme ça 1 seul transfert dma par icône...
Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 (modifié) yep, je viens juste de re-réduire par deux pour les images.. et en plus elles ne sont plus "ré-affichées" très souvent Modifié (le) Mai 6, 2019 par Epsylon3
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 Ok, je viens de voir ton code. Tout est pret pour mesurer les differentes combinaisons de memcopy et DMA, ou bien double transfert DMA. Je vais mesurer la boucle principale, et tester tout ca. On choisira la plus rapide. Si il reste encore des sauts de pas, il faudra regarder si il n'est pas possible de modifier la preparation du buffer 128x64... Mais c'est l'etape d'apres. case U8G_DEV_MSG_PAGE_NEXT:
Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 (modifié) oui j'ai deja essayé le code async, mais vu qu'on reutilise le meme buffer, ca sert a rien ca affiche la ligne "d'apres" #ifdef LCD_USE_DMA_FSMC if (y > 0) LCD_IO_WaitSequence_Async(); memcpy(&buffer[256], &buffer[0], 512); if (y == 7) LCD_IO_WriteSequence(buffer, 512); // last line of page else LCD_IO_WriteSequence_Async(buffer, 512); pour info U8G_DEV_MSG_PAGE_NEXT est appelé 8x = 8 bandes sur l'écran (central/dogm) Modifié (le) Mai 6, 2019 par Epsylon3
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 Yep, 8 fois. Et c est peut être la que nous agirons... à voir
Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 (modifié) enfin j'ai une autre piste... DATA: [=== ] 26.3% (used 17240 bytes from 65536 bytes) PROGRAM: [==== ] 42.5% (used 222668 bytes from 524288 bytes) vs DATA: [== ] 23.2% (used 15192 bytes from 65536 bytes) PROGRAM: [==== ] 42.5% (used 222652 bytes from 524288 bytes) si je rajoute un 2e buffer de 512 uint16_t Modifié (le) Mai 6, 2019 par Epsylon3
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 (modifié) On a de la place! Profitons en un peu. C est sur que c ´est plus simple comme solution si ça marche Modifié (le) Mai 6, 2019 par Hobi
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 Euhhh en étant bourrin 8 buffers... un gros frame buffer...
Epsylon3 Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 yep, bon apres, ca complique le code et ca doit se mesurer en 0.x% l'amélioration
Hobi Posté(e) Mai 6, 2019 Posté(e) Mai 6, 2019 @Epsylon3 LCD_IO_WriteSequence(buffer, 512); // last line of last page J'aurai laisse la derniere write sequence asynchrone, pour que le DMA travaille de son cote, et finisse le job pendant que le CPU commence autre chose... Ceci impose de mettre avant le premier write sequence async le test LCD_IO_WaitSequence_Async();
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant