Faire en sorte que le bus partagé agisse comme OU

10

Pour les impatients, vous pouvez sauter l'arrière-plan.

Contexte

Je programme un ensemble de microcontrôleurs qui communiquent avec SPI. Il y a un maître et des nesclaves qui partagent le bus. Il n'y a pas de sélection de puces. (Ce n'est pas un mauvais design, mais il nest grand et il n'y a pas assez d'espace pour ndes lignes supplémentaires).

Il est donc de la responsabilité des esclaves de maintenir leur MISO sous haute impédance et tout au plus l'un d'eux parle. Cela se fait en répondant uniquement lorsque leur identifiant est interrogé.

Maintenant, nous aimerions avoir une première phase de découverte où le maître découvre les esclaves avec quels identifiants y sont attachés. Pour vous faciliter la vie (sur certains aspects), nous aimerions avoir l'identifiant unique (et donc par exemple 32 bits). Cela empêche le maître de simplement interroger les identifiants un par un et de voir qui répond (il y a trop de possibilités).

Pour résoudre ce problème, j'ai imaginé une variante de recherche binaire où les esclaves répondent collectivement et le maître est capable de trouver rapidement l'id minimum. L'esclave avec cet identifiant est invité à ne plus participer et l'algorithme se répète. (Détails sans importance).

Il y a cependant un problème. La réponse collective doit être le OU logique (ou ET logique) de toutes les réponses. On m'a dit que la ligne peut être configurée de telle manière que le bus MISO puisse agir comme un OU logique. Ce qu'on m'a dit, c'est:

  • Réglez MISO sur le maître comme Pull-up et
  • Réglez MISO sur chaque esclave en tant que drain ouvert.

J'ai essayé cela, mais même avec un seul esclave, cette configuration ne fonctionne pas (l'oscilloscope affiche un zéro constant sur la ligne). Si je configure MISO sur le maître comme entrée haute impédance, je peux voir avec l'oscilloscope que la tension chute de moitié où les bits des sorties de deux esclaves diffèrent (fondamentalement, je présume un court-circuit).

Remarque: en configurant MISO sur le maître en haute impédance et les esclaves chacun en push-pull, je peux parler à chacun d'eux individuellement même s'il y en a beaucoup sur le même bus. Je veux dire, je doute que ce soit un problème de la ligne elle-même.

Question

Ma question est, si cela est possible, et si oui, comment puis-je configurer les broches d'entrée et de sortie du maître et des esclaves afin que la ligne MISO partagée agisse comme OU logique (ou ET logique)?


Éditer

  1. Il s'est avéré que cela devient un OU avec une logique négative-vraie (essentiellement un ET).

  2. Le problème avec un seul esclave a été résolu en écrivant 1 sur la broche de traction du maître. Auparavant, il avait un état initial de 0.

Modifier 2

Il s'est avéré que l'esclave ST remplace ma configuration GPIO de MISO en tant que drain ouvert et le forçait à un niveau élevé lors de l'écriture. J'ai résolu de faire taire SPI et de sortir MISO dans ce cas particulier manuellement.

Shahbaz
la source
Je détesterais demander, car je suis sûr que vous y avez pensé, mais avez-vous envisagé d'utiliser I2C ou CAN? Ils sont conçus pour n appareils, alors que SPI est vraiment conçu pour être utilisé avec une puce sélectionnée pour chaque appareil.
Bob
@bob, oui. Ils sont trop lents. Quoi qu'il en soit, si la réponse à ma question est "c'est impossible", alors nous aurions juste à faire un peu de travail manuel, mais le produit final est toujours bien meilleur avec SPI.
Shahbaz
1
C'est dommage que vous utilisiez 32 bits comme adresse parce que si vous utilisiez 24 bits (16 772 216 variations) vous pourriez envoyer une commande "découvrir" et attendre 16 772 216 horloges et vous pourriez avoir toutes vos informations esclaves. À 10 Mbps, cela prendrait moins de 2 secondes et aucun affrontement à comprendre. Hé ho - tu me fais penser alors +1 pour ça.
Andy aka
@Andyaka, 24 bits peut également être pas mal (mais 32 bits est certainement mieux). si je vous ai bien compris, vous voulez dire que chaque esclave répond à sa première horloge par un 1 et le maître regarde quelles horloges en ont généré un? Ce n'est pas mal, sauf que les esclaves répondent en octets. Donc, chaque esclave répond avec 8 bits, et à moins que je ne puisse faire fonctionner le bus comme OU, la réponse d'un esclave est "perdue" dans les réponses de l'autre esclave (le 1 d'un esclave est abaissé par le 0 de tous le reste).
Shahbaz
@Shahbaz si vous avez le contrôle sur le code de l'esclave, vous pouvez en faire un "spécial" où l'esclave ne répond qu'avec 1 bit à l'heure allouée. Oui, vous avez compris l'essentiel de mes réflexions.
Andy aka

Réponses:

5

Votre SPI sans sélection est ce que Microchip utilise sur ses puces MCP23017 (et autres). Rien de mal à cette approche.

Oui, ce que vous voulez est possible, mais vous devez obliger les esclaves à être ouverts. Vous pouvez tricher en mettant une diode (schottky) en série avec chaque sortie si vous ne pouvez pas les faire se comporter comme un drain ouvert.

Votre approche d'énumération est la même que celle utilisée par le bus monofil de Dallas pour l'énumération et par le bus CAN pour l'arbitrage.

Mais un sérieux inconvénient de votre approche est que la vitesse est désormais limitée par le temps de montée, entraîné par la résistance de pull-up. Ce sera plus lent que lorsqu'il est entraîné par une sortie push-pull, et limitera probablement la vitesse à laquelle vous pouvez utiliser le bus.

Si vous avez deux broches à épargner sur chaque esclave, vous pouvez les connecter en chaîne et avoir un schéma d'énumération en fonction de leur place dans la chaîne.

Wouter van Ooijen
la source
Oui, j'ai oublié de mentionner qu'on m'a également dit que je devais réduire la vitesse (ce que j'ai fait d'environ 20 fois (de 4 Mbit / s à 128 Kbit / s)). C'est une phase initiale cependant et mon algorithme peut gérer la vitesse plus lente (c'est toujours assez rapide). Malheureusement, je doute que nous reconcevions le matériel maintenant. Le coût est plus que simplement ignorer cette phase et dire au maître à quoi s'attendre.
Shahbaz
Revenons à la question, j'ai déjà configuré les esclaves comme open-drain. Comment dois-je configurer le maître?
Shahbaz
1
Rien de spécial à la broche MISO du maître, sauf le pullup. Je doute que vous atteindrez 128Kbps avec une conception pull-up, mais YMMV. La lecture de certains documents I2C approfondis peut être utile, c'est-à-dire un bus filaire ou pull-up, donc chaque astuce appliquée peut vous aider.
Wouter van Ooijen
Merci beaucoup. Je vais essayer de ralentir encore plus l'autobus pour voir ce qui se passe. Je suppose que je dois enfin étudier et comprendre ce que ces pull-up, open-drain et autres signifient réellement. (Ingénieur logiciel ici!)
Shahbaz
1
Mettez un oscilloscope sur le bus et vérifiez ce qui se passe. Le temps de montée peut être trop lent, mais il peut aussi y avoir une sonnerie.
Wouter van Ooijen
4
  • Réglez MISO sur le maître comme Pull-up et
  • Réglez MISO sur chaque esclave en tant que drain ouvert.

J'ai essayé cela, mais même avec un seul esclave, cette configuration ne fonctionne pas (l'oscilloscope affiche un zéro constant sur la ligne).

Vous devez vérifier quelle est la résistance équivalente de la broche d'E / S principale en mode pull-up.

En règle générale, le mode pull-up a une résistance très élevée, peut-être 50 kOhms ou plus. Il est destiné à empêcher la broche de scintiller en raison de l'émi ou d'autres bruits, ou de définir une valeur par défaut pour les signaux de contrôle très lents, et en même temps de ne pas gaspiller trop d'énergie à le faire.

Comme l'a souligné Wouter, dans un bus à drain ouvert, la vitesse est limitée par la résistance de rappel. Des valeurs de résistance plus élevées rendent le bus plus lent. Les valeurs typiques en I2C (qui obtient 100 ou 400 kHz) sont de 1 à 5 kOhms. Vous voudrez une résistance à la traction similaire afin d'atteindre une vitesse similaire.

Je pense que vous devez utiliser une résistance de rappel externe (de 1 à 5 kOhms environ) plutôt que le pull-up des broches d'E / S du maître pour faire fonctionner ce schéma.

Le photon
la source
Merci pour les indices. Je ne suis pas un mec de l'électronique, mais je devrais demander à mon collègue de jeter un œil à votre suggestion. J'ai besoin du filaire ou seulement pour une phase initiale du programme et dans la phase normale, la broche n'est pas configurée comme pull-up. Une résistance externe n'est donc probablement pas une option.
Shahbaz
Si vous avez une broche d'E / S libre sur le micro maître, vous pouvez la connecter au bus, par exemple, 5 kOhms. Ensuite, tournez-le vers le haut pendant l'énumération du bus et tournez-le vers le haut-Z pendant la communication normale.
The Photon
1

Pour qu'un câble et un bus fonctionnent, les nœuds du bus doivent être à drain ouvert, c'est-à-dire qu'ils doivent transmettre

  • la logique basse en tirant fortement vers le bas, et
  • la logique haute en se déconnectant du bus.

De plus, l'autobus doit être tiré légèrement vers le haut.

Le comportement particulier que vous voyez avec un seul maître non émetteur et un seul esclave émetteur peut être expliqué soit par le maître tirant fortement, soit par l'esclave baissant faiblement.

Vous devez déterminer lequel des événements ci-dessus se produit.

Mettez l'esclave en mode haute impédance et connectez le bus à la terre via une résistance 10k. Si la tension de ligne ne change pas de manière significative, le maître tire fortement et vous devez y remédier. Sinon, faites la même procédure avec l'esclave (connectez cette fois la résistance à Vcc); si la tension de ligne augmente de manière significative, l'esclave tire vers le bas faiblement (corrigez cela). Sinon, recherchez les distorsions spatio-temporelles dans la zone autour de vous.

avakar
la source
Excusez mon ignorance en électronique, mais si l'esclave s'abaisse fortement, cela ne fait-il pas que le bus agisse comme ET? Je dis que les esclaves qui veulent haut se déconnectent et ceux qui veulent bas se retirent, donc le résultat global est en baisse, non?
Shahbaz
@Shahbaz, ma mauvaise, bien sûr, le bus sera câblé et j'ai corrigé la réponse. Si vous voulez câblé ou inversez simplement les polarités (le maître tire doucement, les esclaves tirent fortement).
avakar
En lisant dans wikipedia, j'ai réalisé qu'ils se référaient à cela comme câblé et / ou câblé ou avec une logique négative-vraie.
Shahbaz
1

Je suggérerais d'avoir un pull-up ou un pull-down passif sur le bus (je suppose que le pull-up) et d'avoir des esclaves conduisent activement le bus (conduisant haut et conduisant bas) quand ils ont quelque chose à dire et le font flotter autrement . Avoir des commandes d'adresse de requête qui prennent une adresse et un masque et ordonnent à chaque esclave de sortir 00 ou de ne rien faire (continuer à faire flotter sa sortie) selon qu'il aime l'adresse et le masque. Si possible, demandez au maître de conduire activement le bus haut quelque temps avant que les esclaves ne commencent à le conduire. Selon la force du pull-up et si le maître pousse le bus vers le haut, avant que les esclaves ne soient autorisés à le tirer vers le bas, il peut être nécessaire de limiter la vitesse du bus pendant la phase de configuration. D'un autre côté, une fois la configuration terminée,

supercat
la source
Si deux esclaves conduisent activement haut et bas, que dois-je lire du bus?
Shahbaz
Il faut éviter d'avoir un esclave essayant de rouler haut tandis qu'un autre roule bas. Un esclave ne doit conduire le bus que lorsque (1) il sait que ce sera la seule chose à faire, ou (2) il sait que lui et tous les autres qui conduisent le bus le conduiront à l'opposé de son ralenti passif. Etat.
supercat
Qu'est-ce que cela signifie alors? ... le fait que chaque esclave sélectionné conduise activement les niveaux haut et bas permettra au bus de ...
Shahbaz
@Shahbaz: Quand un esclave a quelque chose à dire, il doit conduire activement le bus haut pour transmettre des bits "1" et bas pour transmettre des bits "0". Lorsqu'un esclave n'a rien à dire, il ne doit pas conduire du tout. Notez que le fait d'avoir des esclaves conduisant activement le bus haut lorsqu'ils veulent envoyer des bits "1" permettra au bus de fonctionner beaucoup plus rapidement que de se fier à un pull-up passif pour conduire le bus haut.
supercat
@Shahbaz: Ce que le supercat essaie de dire, c'est que dans l'état d'énumération, une résistance devrait remonter la ligne, et les esclaves devraient seulement envoyer "0" ou rien (sortie drain ouvert), mais ensuite, en communication normale, seulement un un seul esclave doit être actif à la fois et l'esclave actif doit envoyer "0" ou "1" (sortie normale). Ainsi, la résistance de rappel et la capacité de ligne ne limitent que le débit binaire pendant l'énumération. Ensuite, dans une communication normale, le débit binaire peut être plus élevé, comme le permet la conduite active.
Laszlo Valko