Messages récents

Pages: [1] 2 3 ... 10
1
Vos projets / Re : Les nouveaux AVR: coeur AVRx avec MEGACOREX, DXCORE, MEGATINYCORE
« Dernier message par laurentr le Aujourd'hui à 10:15:40 pm »
Au travers des exemples mis en œuvre nous avons déjà couvert simplement l'utilisation de:

LOGIC
EVENT

A l'aide de ces éléments avec une syntaxe "simplifiée" sur laquelle il faut être rigoureux,  nous pouvons déjà bien combiner de multiples cas d'usage de ces hardwares méconnus

Je vous propose ensuite de passer à COMPARATOR.

Stop ou encore?

Ltr
2
Vos projets / Re : Les nouveaux AVR: coeur AVRx avec MEGACOREX, DXCORE, MEGATINYCORE
« Dernier message par laurentr le Aujourd'hui à 10:07:33 pm »
Bon c est bien mais si je ne veux pas non plus me servir de la broche PIN_PB6 y a  t il d autres solutions?

OUI

Pour cela nous allons de nouveau nous servir de EVENT pour établir une liaison entre la sortie du LUT2 et une broche de type EVOUTx
X étant le port en question

La aussi parfois plusieurs solutions sont offertes pour sélectionner la broche précise parmi un choix limité.

Toujours dans notre exemple à base de ATTINY1626 nous allons router la sortie vers le port A sur une broche supportant l'EVOUTA

Sont alors possibles les choix suivant:
choix par défaut PIN_PA2
choix alternatif PIN_PA7

pour cela il nous faudra préciser les valeurs attendues




puis voici le code complet:



#include "Logic.h"

#include "Event.h"

//PIN_PB0 PIN_PB1 and PIN_PB3 are mapped by default on LOGIC BLOCK CCL LUT2

void INIT_LOGIC_BLOCK2()
{
  Logic2.enable;                          //ENABLE LUT2
  Logic2.input0 = logic::in::input;       //input PIN_PB0
  //Logic2.input1 = logic::in::input;     //input PIN_PB11
  Logic2.input1 = logic::in::event_a;     //event_a OF LUT2
  Logic2.input2 = logic::in::masked;      //masked = not used
  //Logic2.output = logic::out::enable;   //active output
  Logic2.output = logic::out::disable;   //disable output
  //Logic2.output_swap = logic::out::no_swap;    // Use position, pin 3 on the port so here PIN_PB3
  //Logic2.output_swap = logic::out::pin_swap;   // Use alternative position, pin 6 on the port so here PIN_PB6
  Logic2.truth = 0x08;                    //AND OUT ON IF BOTH IN ARE HIGH

  Logic2.init();
  Logic2.start();
   
}

void INIT_EVENT()
{
  Event0.assign_generator_pin(gen0::pin_pa1);
  Event0.set_user(user::ccl2_event_a);          //EVENT A OF LUT2

  Event0.start();

  Event1.assign_generator(gen::ccl2_out);
  //Event1.set_user_pin(user::evouta_pin_pa2); //route on PA2
  Event1.set_user_pin(user::evouta_pin_pa7); //route on PA7

  Event1.start();
 
}


Pour memo le fait de passer d un port X vers un autre s appelle le "MUXING" ou routage.

Vous verrez souvent dans les datasheet le terme PORTMUX.  C'est cette fonctionnalité qui permet dans les limites du possible du hardware de permuter les attributions de broches selon des choix pré définis.
3
Vos projets / Re : Les nouveaux AVR: coeur AVRx avec MEGACOREX, DXCORE, MEGATINYCORE
« Dernier message par laurentr le Aujourd'hui à 09:48:37 pm »
Le tableau de la page 18 nous indique que le LUT2 peut

sortir sur la broche PIN_PB3
sortir sur la broche PIN_PB6

Par défaut avec la ligne

Logic2.output = logic::out::enable;     //enable OUTPUT PIN le routage se fait sur la broche par défaut soit PIN_PA3 ( la librairie met par défaut la broche usuelle

La ligne suivante n'est donc pas obligatoire mais sera mise pour être complet.:

Logic2.output_swap = logic::out::no_swap; //use PIN_PA3 as OUTPUT for LUT2 

Pour un routage vers la broche alternative PIN_PB6 il faut saisir ceci:


Logic2.output = logic::out::enable;     //active OUTPUT
Logic2.output_swap = logic::out::pin_swap; // Use alternative position, pin 6 on the port so here PIN_PB6

d où le code complet:



#include "Logic.h"

#include "Event.h"

//PIN_PB0 PIN_PB1 and PIN_PB3 are mapped by default on LOGIC BLOCK CCL LUT2

void INIT_LOGIC_BLOCK2()
{
  Logic2.enable;                          //ENABLE LUT2
  Logic2.input0 = logic::in::input;       //input PIN_PB0
  //Logic2.input1 = logic::in::input;     //input PIN_PB11
  Logic2.input1 = logic::in::event_a;     //event_a OF LUT2
  Logic2.input2 = logic::in::masked;      //masked = not used
  Logic2.output = logic::out::enable;     //active output
  //Logic2.output_swap = logic::out::no_swap;    // Use position, pin 3 on the port so here PIN_PB3
  Logic2.output_swap = logic::out::pin_swap;   // Use alternative position, pin 6 on the port so here PIN_PB6
  Logic2.truth = 0x08;                    //AND OUT ON IF BOTH IN ARE HIGH

  Logic2.init();
  Logic2.start();
   
}

void INIT_EVENT()
{
  Event0.assign_generator_pin(gen0::pin_pa1);
  Event0.Event3.set_user(user::ccl2_event_a);          //EVENT A OF LUT2

  Event0.start();
 
}

void setup() {

  PORTA.DIRCLR = PIN1_bm; //INPUT for PIN_PA1 = pinMode(PIN_PA1,INPUT) but faster!!

  INIT_EVENT();
 
  INIT_LOGIC_BLOCK2();

}

void loop() {
 

}


Rm: A noter que par défaut la librairie mettra en œuvre par défaut la valeur no_swap si vous ne l'avez pas saisie! (ouf!)
4
Vos projets / Re : Les nouveaux AVR: coeur AVRx avec MEGACOREX, DXCORE, MEGATINYCORE
« Dernier message par laurentr le Aujourd'hui à 09:26:32 pm »
Et si maintenant on désire utiliser une autre broche mais qui n'est pas celle disponible par défaut en entrée sur le bloc logique?

Est ce possible?

La réponse est OUI!

Comment va t on faire?

Cela n'est pas immédiat et il faut faire appel à un autre composant de ce hardware moderne: le bloc EVENT.

EVENT:

EVENT est ce qu on pourrai appeler un élément de liaison entre un producteur et un consommateur.
Ceux ci peuvent être de différentes natures

Le producteur appelé GENERATOR (Générateur) est toujours unique sur une entrée d EVENT

En revanche les consommateurs appelés USERS peuvent être multiples. C'est à dire que l'on peut aiguiller parallèlement une même information à plusieurs consommateurs USERS.

Prenons un cas simple complémentaire de notre exemple précèdent.

Nous voulons non plus utiliser la broche PIN_PB1 en entrée mais la broche PIN_PA1.

Nous devons alors:
déclarer PIN_PA1 comme INPUT
déclarer PIN_PA1 comme GENERATOR
attribuer un consommateur.
Lier de ce consommateur sur l'entree 1 du bloc logique à la place de PIN_PB1
Ici nous voulons une liaison sur la deuxième entree du bloc logic2
Nous pouvons par exemple definir la sortie event_a du blog logique 2.


Cela se traduit comme ceci:


#include "Logic.h"

#include "Event.h"

//PIN_PB0 PIN_PB1 and PIN_PB3 are mapped by default on LOGIC BLOCK CCL LUT2

void INIT_LOGIC_BLOCK2()
{
  Logic2.enable;                          //ENABLE LUT2
  Logic2.input0 = logic::in::input;       //input PIN_PB0
  //Logic2.input1 = logic::in::input;     //input PIN_PB1
  Logic2.input1 = logic::in::event_a;     //event_a OF LUT2
  Logic2.input2 = logic::in::masked;      //masked = not used
  Logic2.output = logic::out::enable;     //enable OUTPUT
  Logic2.output_swap = logic::out::no_swap; //use PIN_PA3
  Logic2.truth = 0x08;                    //AND OUT ON IF BOTH IN ARE HIGH

  Logic2.init();
  Logic2.start();
   
}

void INIT_EVENT()
{
  Event0.assign_generator_pin(gen0::pin_pa1);
  Event0.set_user(user::ccl2_event_a);          //EVENT A OF LUT2

  Event0.start();
 
}

void setup() {

  PORTA.DIRCLR = PIN1_bm; //INPUT for PIN_PA1 = pinMode(PIN_PA1,INPUT) but faster!!

  INIT_EVENT();
 
  INIT_LOGIC_BLOCK2();

}

void loop() {
 

}



Pratique!

Et si on désire changer la sortie? comment procéder?

2 cas de figures sont possibles mais les combinaisons sont plus limitées.
Il faut donc regarder les autres contraintes que nous rencontrerons dans le reste du montage et des conditions de fonctionnement pour faire un choix judicieux!

Nous allons le traiter dans l'exemple suivant.

5
Vos projets / Re : Les nouveaux AVR: coeur AVRx avec MEGACOREX, DXCORE, MEGATINYCORE
« Dernier message par laurentr le Aujourd'hui à 09:02:29 pm »
Poursuivons ici avec l'utilisation de la librairie LOGIC toujours avec les mêmes broches:



#include "Logic.h"

//PIN_PB0 PIN_PB1 and PIN_PB3 are mapped by default on LOGIC BLOCK CCL LUT2

void INIT_LOGIC_BLOCK2()
{
  Logic2.enable;                          //ENABLE LUT2
  Logic2.input0 = logic::in::input;       //input PIN_PB0
  Logic2.input1 = logic::in::input;       //input PIN_PB1
  Logic2.input2 = logic::in::masked;      //masked = not used
  Logic2.output = logic::out::enable;     //use OUTPUT
  Logic2.output_swap = logic::out::no_swap; // use PIN_PB3 as OUTPUT
  Logic2.truth = 0x08;                    //AND OUT ON IF BOTH IN ARE HIGH

  Logic2.init();
  Logic2.start();
   
}

void setup() {

  INIT_LOGIC_BLOCK2();

}

void loop() {
 

}



Il n'y a plus de code dans la boucle principale, tout se fait en HARD et SANS aucune intervention du CPU!

Ltr

6
Vos projets / Re : Les nouveaux AVR: coeur AVRx avec MEGACOREX, DXCORE, MEGATINYCORE
« Dernier message par laurentr le Aujourd'hui à 08:49:16 pm »
Prenons un exemple simple pour illustrer:

Nous travaillons avec un ATTINY1626.

https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/DataSheets/ATtiny1624-26-27-DataSheet-DS40002234B.pdf

Voir la tableau page 18 qui reprend les attributions de broches.


CAS: AND à 2 entrées:

Dans un code habituel nous ferions la lecture de 2 entrées et nous ferions l'association de leur état pour produire une sortie selon la combinaison en entrée


/*
 * WE USE:
 * PIN_PB0 PIN_PB1 as INPUT
 * PIN_PB3 as OUTPUT
 */

#define ENTREE_1 PIN_PB0
#define ENTREE_2 PIN_PB1

#define SORTIE_1 PIN_PB3

void setup() {
  // put your setup code here, to run once:

  pinMode(ENTREE_1,INPUT);
  pinMode(ENTREE_2,INPUT);

  pinMode(SORTIE_1,OUTPUT); 

}

void loop() {

  bool IN1 = digitalRead(ENTREE_1);
  bool IN2 = digitalRead(ENTREE_2);

  bool OUT_STATE = IN1 & IN2;

  digitalWrite(SORTIE_1,OUT_STATE);

}


Ce code est optimisable car les utilisations des fonctions digitalRead(), digitalWrite() sont gourmandes en temps.
Nous utiliserions pour cela de mode de manipulation direct des ports (et donc l'écriture dans les registres)

Explications ici par exemple:
https://github.com/SpenceKonde/DxCore/blob/master/megaavr/extras/DirectPortManipulation.md

On utilise aussi 3 des 4 registres internes pouvant stoker chacun 1 byte.
Leur accès est ce qui est le plus rapide

Code optimisé:

#define SORTIE1_ON  PORTB.OUTSET = PIN3_bm
#define SORTIE1_OFF PORTB.OUTCLR = PIN3_bm

#define IN1 GPIOR0
#define IN2 GPIOR1
#define OUT_STATE GPIOR3


void setup() {
  // put your setup code here, to run once:

  //PIN_PB0 AS INPUT:
  PORTB.DIRSET = PIN0_bm;

  //PIN_PB1 AS INPUT:
  PORTB.DIRSET = PIN1_bm;

  //PIN_PB3 AS OUTPUT
  PORTB.DIRCLR = PIN3_bm;

}

void loop() {
  // put your main code here, to run repeatedly:

  IN1 = PORTB.IN & PIN0_bm;
  IN2 = PORTB.IN & PIN1_bm;

  OUTSTATE = IN1 & IN2;

  if(OUTSTATE)
  {
    SORTIE1_ON;
  }
  else
  {
    SORTIE1_OFF;
  }
}


En revanche nous avons perdu ici la "portabilité" du code d'un hardware vers un autre au bénéfice d'une performance accrue sur le hardware dédié.



7
Vos projets / Re : centrale DCC / analogique modulaire
« Dernier message par laurentr le Aujourd'hui à 08:21:49 pm »
Historiquement le rapport du cout pour  passer de 2 vs 4 couches était d un rapport de 1 à 4

C'est restait plutôt stable, voir même le cout du 4 couches a baissé

A noter que le format 100mmx100mm ( 10x10cm) est moins pénalisant coté cout qu'autrefois.

En revanche les prix du port ont "explosé"!

Pour le montage c est selon... mais il y a quelques astuces pour optimiser:
respecter la taille mini du 70mmx70mm y compris avec des bords "edges" additionnels pour y parvenir.
choix de composants en évitant si possible les "extended"
garder tout ce qui est traversant à implanter soit même.( connecteurs notamment, relais,...)

en cas de petites séries rester sur des couleurs et épaisseurs "ordinaires" type 1.6mm/vert
équiper 2/5 des pcb fabriqués.

garder un oeil entre les multiples de couts des pièces et leur nombre à implanter.
enfin rester sous les 150€ pour ne pas avoir de taxes supplémentaires à devoir acquitter...

Ltr


Ltr
8
Vos projets / Re : centrale DCC / analogique modulaire
« Dernier message par lebelge2 le Aujourd'hui à 07:29:48 pm »
Bonjour.

Assemblage PCB:

Juste pour vous informer que je  viens de faire une simulation pour un double face et les prix ont fortement augmenté chez JLCPCB.
Pour ma part, je ne ferai plus que des simples faces....
Alors pour un quatre couches……
9
Vos projets / Re : Les nouveaux AVR: coeur AVRx avec MEGACOREX, DXCORE, MEGATINYCORE
« Dernier message par laurentr le Aujourd'hui à 06:22:57 pm »
Dans l'exemple donné vous remarquerez qu'il n'est pas nécessaire de déclarer en INPUT et OUTPUT les broches.

La librairie du framework va s'en occuper tt seule comme une grande.  8)

Il peut en être différemment lorsque l'on combine des éléments plus complexes entre eux!

Voir l'exemple de code plus complet donné dans le post: https://forum.locoduino.org/index.php?topic=1707.0 pages 4 et 5.

Ltr
10
Vos projets / Re : Les nouveaux AVR: coeur AVRx avec MEGACOREX, DXCORE, MEGATINYCORE
« Dernier message par laurentr le Aujourd'hui à 06:10:52 pm »
On retrouve dans ces framworks des librairies qui vont piloter des couches hardware de ces processeurs.

On peut naturellement se passer de leur apport mais il faudra dans ce cas re écrire une bonne partie de code pour piloter ces éléments hardware.

Autant bénéficier des solutions "universelles" déjà testées et approuvées par une large communauté.
Ces framework étant à présent "matures" et continue d'évoluer pour prendre en comptes des correctifs ou de nouveaux CPU.

Nous avons évoqué précédemment des composants additionnel sur ces nouvelles puces.

Nous allons en traiter 3 ici:
le "GLU LOGIC"
le "COMPARATOR"
l "EVENT"

Chacun dispose de sa bibliothèque et pour l utiliser nous ajouterons  en tête de programme:
#include "nom_de_la_librairie;h"
Maintenant de quoi retourne t il:
GLU LOGIC:
C est en fait un ensemble de portes logiques configurables à la demande.
On peut disposer sur chaque bloc logique appelé LUT de 3 entrées et d'une sortie.
Ces entrées et sorties peuvent être de différentes natures: entrée de pins, event, état d'un composant interne,...
De nombreuses combinaisons sont offertes et il est même possible dans certaines conditions de chainer ces portes logiques.

L intérêt de cette logique programmée est qu'elle est INDEPENDANTE des ressources du coeur du CPU. = elles n'utilisent pas de ressources du cœur du CPU pour fonctionner.
C est l'équivalant de composants externes placés dans la puce comme "bonus" en étant en plus très rapides, moins encombrant et donc globalement plus performant.

A titre d exemple voici un paramétrage du 3eme LUT ( 3eme bloc logique):

sur un ATTINY1626: (MEGATINY1626)

  //LOGIC LUT3:
    Logic3.enable;                                //ENABLE LUT3
    Logic3.input0 = logic::in::ac;           //AC0 level OUT : sortie du comparateur
    Logic3.input1 = logic::in::input;       //PC1 input : correspond ici à la broche PC1
    Logic3.input2 = logic::in::event_a;   //evenement_a
    Logic3.output = logic::out::enable;  //output on PIN PA5
    Logic3.truth = 0x0a;                       //table de vérité de combinaison des 3 entrées input0, 1 ,2: =10 = 0x0a ==> la sortie est a 1 quand uniquement l'entrée input2 est à 1. sinon 0

    Logic3.init();
    Logic3.start();


Cette exemple, non le plus simple, montre surtout la diversité des éléments combinables et il sera surement plus simple dans vos premières mises en œuvre de test de réaliser les exemples fournis par ces frameworks. ( NAND, AND, NOR, XOR, OR,...)

N'hésitez pas à commenter ces premiers éléments de présentation pour que nous l'enrichissions collectivement.

Ltr
Pages: [1] 2 3 ... 10