Posté le 18/07/2019 18:57
Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 258 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd
Citer : Posté le 18/07/2019 22:09 | #
Merci !
Allez hop et un topic résolu en un soir !
Citer : Posté le 18/07/2019 22:10 | #
Bien joué ! Si ton code est à peu près clean tu peux soumettre une pull request...
Citer : Posté le 18/07/2019 22:30 | #
Donc au niveau du code
Donc rajouter de lasm pour prendre en compte le channel 1 et je modifie un peu ta fonction pour choisir dynamiquement le bon channel, c'est ça ?
Citer : Posté le 18/07/2019 22:31 | #
Oui, c'est ça ! Si possible dans dma_setup() ne pas c/c le code de configuration mais utiliser un pointeur.
Citer : Posté le 18/07/2019 22:36 | #
Dans les arguments ?
Citer : Posté le 18/07/2019 22:38 | #
Hmm, je dirais prendre le numéro de channel en argument (0/1/2) et ensuite calculer le pointeur (&DMA.DMA{0,1,2}) à l'intérieur de la fonction.
Citer : Posté le 18/07/2019 22:46 | #
Au niveau de init, il faut mettre quelles adresses pour gint_int_handler
Citer : Posté le 18/07/2019 22:49 | #
0x800 pour le channel 0, 0x820 pour le 1, 0x840 pour le 2 et il semble y en avoir un dernier, qui serait 0x860 à tester.
Citer : Posté le 18/07/2019 22:49 | #
Allez hop je t'écrirai aussi dma_memset et dma_memcpy, avec les parametres standards
Ajouté le 19/07/2019 à 11:22 :
du coup du coté de inth.s c'est bon :
** gint:dma:inth - Interrupt handler for the DMA
** An easy one, just clears some flags and marks all transfers as finished.
*/
.global _inth_dma_dma0
.section .gint.blocks, "ax"
.align 4
/* DMA TRANSFER ENDED INTERRUPT HANDLER - BYTES */
_inth_dma_dma0:
/* Clear the TE flag and DMA Enable in CHCR */
mov.l 1f, r1
mov.l @r1, r0
mov #-4, r2
and r2, r0
mov.l r0, @r1
/* Clear the AE and NMIF flags in OR, and cut the master switch */
add #0x34, r1
mov.w @r1, r0
shlr8 r0
shll8 r0
mov.w r0, @r1
rte
nop
nop
nop
.global _inth_dma_dma1
.section .gint.blocks, "ax"
.align 4
_inth_dma_dma1:
/* Clear the TE flag and DMA Enable in CHCR */
mov.l 2f, r1
mov.l @r1, r0
mov #-4, r2
and r2, r0
mov.l r0, @r1
/* Clear the AE and NMIF flags in OR, and cut the master switch */
add #0x34, r1
mov.w @r1, r0
shlr8 r0
shll8 r0
mov.w r0, @r1
rte
nop
nop
nop
.global _inth_dma_dma2
.section .gint.blocks, "ax"
.align 4
_inth_dma_dma2:
/* Clear the TE flag and DMA Enable in CHCR */
mov.l 3f, r1
mov.l @r1, r0
mov #-4, r2
and r2, r0
mov.l r0, @r1
/* Clear the AE and NMIF flags in OR, and cut the master switch */
add #0x34, r1
mov.w @r1, r0
shlr8 r0
shll8 r0
mov.w r0, @r1
rte
nop
nop
nop
1: .long 0xfe00802c /* CHCR0 - OR is 0x34 bytes after this */
2: .long 0xfe00803c
3: .long 0xfe00804c
Ajouté le 19/07/2019 à 11:31 :
mais par contre pour calculer automatiquement le pointeur j'ai des doutes :
je le met de type void* ?
Pour calculer DMA.DMAx ça c'est ok :
Mais du coup, pour l'exploiter, est-ce que j'ai le droit de faire par exemple
est-ce que il faut modifier les fonctions en "ctx_" ? Je n'ai pas vraiment compris à quoi elles servent
Enfin, pour ce qui est du memset et memcpy, pour l'instant je ne sais pas si on peut écrire octet par octet avec le DMA, et j'en ai pas particulièrement besoin en fait
Citer : Posté le 19/07/2019 12:47 | #
C'est pas mal, merci ! Queques remarques sur l'assembleur. Ces deux lignes ne sont pas nécessaires :
.align 4
puisque la section est déjà définie et l'alignment est préservé au-dessus (au contraire si le bloc au-dessus fait pas un multiple de 4 en taille je préfère que ça plante avec une erreur de compil' parce que c'est pas normal !).
Pour la suite, si tu veux accéder au registre OR, c'est 0x34 octets avec CHCR0, mais du coup par rapport à CHCR1 c'est 0x24 et par rapport à CHCR2 c'est 0x14. Couper le master switch arrête tous les DMAs en même temps donc c'est probablement quelque chose à modifier mais je m'occuperai de la doc pour trouver comment...
Comme ces gestionnaires d'interruption sont tous des blocs de taille fixe, c'est bien qu'ils soient "free-standing". En particulier les données doivent être à la fin des blocs parce que le repositionnement va casser les références indirectes. Les adresses des CHCR devraient donc être à la fin de chaque bloc ; tu peux aussi vérifier que chaque gestionnaire doit faire exactement 32 octets.
Pour calculer DMA.DMAx ça c'est ok :
Le plus clean c'est de compter en octets, auquel cas ce serait :
Note que tu peux aussi caster 0xfe008020 en void* puis calculer dessus puisque dans GCC l'arithmétique de void* est par octet. Le cast est important sinon tu ne peux pas accéder aux données ensuite !
Une fois que tu as casté c'est bon, à la notation près :
J'ai remarqué que dans mon header <gint/mpu/dma.h> j'ai documenté 6 channels différents en fait. S'il en existe bien 6 alors je paramétrerai le code et les interrupt handlers pour éviter d'avoir 6 fois la même chose, ce qui serait dommage.
Ces fonctions servent à sauvegarder l'état complet du DMA dans un objet de type ctx_t (contexte) puis à le restaurer à la fin. C'est parce que gint prend le contrôle du matériel mais doit ultimement le rendre au système d'exploitation, et donc restaurer tous les paramètres à leur état initial. Comme le driver modifie maintenant le DMA1/2, il faut aussi les sauvegarder - donc rajouter des éléments dans ctx_t et copier plus de choses, avec une boucle certainement. Si tu as un doute je le ferai.
Tu peux mais c'est pas intéressant ! Laisse par blocs de 32 octets, on documentera que ces fonctions ne sont que pour des blocs 32-alignés avec des tailles multiples de 32 et puis c'est tout.
Merci encore pour ton aide !
Citer : Posté le 19/07/2019 14:05 | #
A quoi correspond le premier argument de gint_intlevel(int,int) ?
Citer : Posté le 19/07/2019 14:09 | #
C'est le numéro d'une position dans les registres IPR* du contrôleur d'interruption. Regarde page 364 de la doc du SH7724 : il suffit de compter de haut en bas et de gauche à droite en partant de 0. Par exemple IPRB & 0x00f0 c'est 6 (DMAC1A sur SH7724 ; vois <gint/mpu/intc.h> pour une liste plus proche du SH7305).
Je vais les nommer parce que c'est trop casse-pieds de suivre les numéros.
Citer : Posté le 19/07/2019 14:23 | #
je ne comprends toujours pas quelle est la valeur que je dois mettre
Citer : Posté le 19/07/2019 14:40 | #
En fait la réponse est "rien" parce que l'interruption que le gint_intlevel() actuel active concerne l'ensemble du DMA donc tous les channels à la fois.