Fazendo o barramento compartilhado agir como OU

10

Para os impacientes, você pode pular o plano de fundo.

fundo

Estou programando um conjunto de microcontroladores que se comunicam com a SPI. Há um mestre e nescravos que compartilham o ônibus. Não há seleção de chip. (Não é um design ruim, mas né grande e não há espaço suficiente para nlinhas extras).

Portanto, é responsabilidade dos escravos manter seu MISO em alta impedância e no máximo um deles falar. Isso é feito respondendo apenas quando o ID deles é pesquisado.

Agora, gostaríamos de ter uma fase inicial de descoberta, na qual o mestre descobre os escravos com quais IDs estão anexados. Para facilitar a vida (em alguns aspectos), gostaríamos de ter o ID exclusivo (e, portanto, por exemplo, 32 bits). Isso torna impossível para o mestre simplesmente pesquisar os IDs um por um e ver quem responde (há muitas possibilidades).

Para resolver esse problema, criei uma variação da pesquisa binária em que os escravos respondem coletivamente e o mestre é capaz de encontrar rapidamente o ID mínimo. O escravo com esse ID é instruído a não participar mais e o algoritmo se repete. (Detalhes sem importância).

Há um problema, porém. A resposta coletiva precisa ser o OR lógico (ou AND lógico) de todas as respostas. Foi-me dito que a linha pode ser configurada de forma que o barramento MISO possa atuar como um OR lógico. O que me disseram é:

  • Defina MISO no mestre como Pull-up e
  • Defina MISO em cada escravo como Dreno aberto.

Eu tentei isso, mas mesmo com um único escravo, essa configuração não funciona (o osciloscópio mostra um zero constante na linha). Se eu configurar o MISO no mestre como entrada de alta impedância, posso ver com o osciloscópio que a tensão cai para a metade, onde os bits das saídas de dois escravos diferem (basicamente curto-circuito, presumo).

Nota: configurando o MISO no mestre como alta impedância e escravos como push-pull, posso conversar com cada um deles individualmente, mesmo que haja muitos deles no mesmo barramento. Quero dizer, duvido que seja um problema da própria linha.

Questão

Minha pergunta é: se isso é possível, e se sim, como posso configurar os pinos de entrada e saída do mestre e dos escravos para que a linha MISO compartilhada atue como OR lógico (ou AND lógico)?


Editar

  1. Acontece que ele se torna um OR com lógica negativa-verdadeira (basicamente um AND).

  2. O problema com o escravo único foi resolvido com a gravação 1 no pino de puxar no mestre. Anteriormente, tinha um estado inicial de 0.

Editar 2

Acontece que o escravo ST substitui minha configuração GPIO do MISO como dreno aberto e a estava forçando quando um foi escrito. Eu resolvi silenciar o SPI e emitir o MISO nesse caso específico manualmente.

Shahbaz
fonte
Eu odiaria perguntar, porque tenho certeza que você pensou nisso, mas você já pensou em usar I2C ou CAN? Eles são projetados para n dispositivos, enquanto o SPI é realmente projetado para ser usado com uma seleção de chip para cada dispositivo.
Bob
@ Bob, sim. Eles são muito lentos. De qualquer forma, se a resposta para minha pergunta for "é impossível", teríamos que fazer um pouco de trabalho manual, mas ainda assim o produto final é muito melhor com o SPI.
Shahbaz 26/09
11
É uma pena que você esteja usando 32 bits como endereço, porque se estivesse usando 24 bits (16.772.216 variações), você poderia enviar um comando "discover" e aguardar 16.772.216 relógios e poderia ter todas as suas informações sobre escravos. A 10 Mbps, levaria menos de 2 segundos e não haveria conflitos para descobrir. Hey ho - você me fez pensar em +1 para isso.
Andy aka
@ Andyaka, 24 bits também pode não ser ruim (mas 32 bits é certamente melhor). se eu entendi direito, você quer dizer que cada escravo responde no seu id'th relógio com 1 e o mestre olha para quais relógios geraram um? Isso não é ruim, exceto que os escravos respondem em bytes. Portanto, cada escravo responde com 8 bits, e, a menos que eu possa fazer o barramento agir como OU, a resposta de um escravo continua "perdida" nas respostas do outro escravo (o 1 de um escravo é puxado pelos 0 de todos os o resto).
precisa saber é o seguinte
@ Shahbaz, se você tiver controle sobre o código do escravo, poderá torná-lo um "especial", onde o escravo só responde com 1 bit no tempo alocado. Sim, você entendeu a essência das minhas reflexões.
Andy aka

Respostas:

5

Seu SPI sem seleção é o que o Microchip usa em seus chips MCP23017 (e outros). Nada de errado com essa abordagem.

Sim, o que você quer é possível, mas você deve fazer com que os escravos fiquem abertos. Você pode trapacear colocando um diodo (schottky) em série com cada saída, se não conseguir que eles se comportem como drenos abertos.

Sua abordagem de enumeração é a mesma usada pelo barramento de um fio de Dallas para enumeração e pelo barramento de CAN para arbitragem.

Mas uma séria desvantagem de sua abordagem é que a velocidade agora é limitada pelo tempo de subida, impulsionado pelo resistor de pull-up. Isso será mais lento do que quando acionado por uma saída push-pull e provavelmente limitará a velocidade na qual você pode operar o barramento.

Se você tiver dois pinos de sobra em cada escravo, poderá encadeá-los em cadeia e ter um esquema de enumeração com base no lugar deles na cadeia.

Wouter van Ooijen
fonte
Sim, esqueci de mencionar que também me disseram que precisava reduzir a velocidade (o que fiz em cerca de 20 vezes (de 4Mpbs para 128Kbps)). Essa é uma fase inicial e meu algoritmo pode lidar com a velocidade mais lenta (ainda é bastante rápida). Infelizmente, duvido que redesenhássemos o hardware agora. O custo é mais do que simplesmente ignorar essa fase e dizer ao mestre o que os IDs devem esperar.
precisa saber é o seguinte
De volta à pergunta, eu já configurei os escravos como dreno aberto. Como devo configurar o mestre?
precisa saber é o seguinte
11
Nada de especial no pino MISO do mestre, exceto no pullup. Duvido que você atinja 128Kbps com um design pull-up, mas YMMV. A leitura de alguns documentos I2C detalhados pode ajudar, ou seja, um barramento de fio ou pull-up, portanto, todos os truques aplicados podem ajudá-lo.
Wouter van Ooijen
Muito obrigado. Vou tentar desacelerar ainda mais o ônibus para ver o que acontece. Acho que tenho que finalmente estudar e entender o que esses pull-up, open-drain e outros realmente significam. (Engenheiro de Software aqui!)
Shahbaz
11
Coloque um osciloscópio no barramento e verifique o que acontece. O tempo de subida pode ser muito lento, mas também pode estar tocando.
Wouter van Ooijen
4
  • Defina MISO no mestre como Pull-up e
  • Defina MISO em cada escravo como Dreno aberto.

Eu tentei isso, mas mesmo com um único escravo, essa configuração não funciona (o osciloscópio mostra um zero constante na linha).

Você precisa verificar qual é a resistência equivalente do pino de E / S mestre no modo pull-up.

Normalmente, o modo pull-up tem uma resistência muito alta, talvez 50 kOhms ou superior. Ele tem como objetivo evitar que o pino sofra falhas devido a emi ou outro ruído, ou para definir um padrão para sinais de controle muito lentos e, ao mesmo tempo, para não desperdiçar muita energia fazendo isso.

Como Wouter apontou, em um barramento de dreno aberto a velocidade é limitada pelo resistor de pull-up. Valores mais altos do resistor tornam o barramento mais lento. Os valores típicos em I2C (que obtém 100 ou 400 kHz) são de 1 a 5 kOhms. Você deseja uma resistência à tração semelhante para obter uma velocidade semelhante.

Eu acho que você precisa usar um resistor de pull-up externo (de 1 a 5 kOhms) em vez do pull-up do pino de E / S do mestre para fazer esse esquema funcionar.

O fóton
fonte
Obrigado pelas dicas. Eu não sou do ramo de eletrônicos, mas teria que pedir ao meu colega de trabalho para dar uma olhada na sua sugestão. Preciso da conexão com fio - ou apenas para uma fase inicial do programa e, na fase normal, o pino não está configurado como pull-up. Então provavelmente o resistor externo não é uma opção.
Shahbaz 26/09
Se você tiver um pino de E / S gratuito no micro mestre, poderá conectá-lo ao barramento por, digamos, 5 kOhms. Em seguida, aumente-o alto durante a enumeração de barramento e aumente-Z alto durante a comunicação normal.
The Photon
1

Para que um barramento com fio e um barramento funcionem, os nós no barramento precisam ser de dreno aberto, ou seja, devem transmitir

  • a lógica baixa, puxando para baixo fortemente, e
  • a lógica é alta desconectando-se do barramento.

Além disso, o ônibus deve ser puxado fracamente.

O comportamento peculiar que você vê com um único mestre não transmissor e um único escravo transmissor pode ser explicado pelo mestre puxando com força ou pelo escravo puxando fracamente.

Você precisa determinar qual das opções acima está acontecendo.

Coloque o escravo no modo de alta impedância e conecte o barramento ao terra através de um resistor de 10k. Se a tensão da linha não mudar significativamente, o mestre estará aumentando fortemente e você precisará corrigi-lo. Caso contrário, faça o mesmo procedimento com o escravo (desta vez, conecte o resistor ao Vcc); se a tensão da linha aumentar significativamente, o escravo está baixando fracamente (conserte isso). Caso contrário, procure distorções no espaço-tempo na área ao seu redor.

avakar
fonte
Desculpe minha ignorância em eletrônica, mas se o escravo puxa fortemente, isso não faz o ônibus agir como E? Estou dizendo que, como os escravos que querem alto estão se desconectando e os que querem baixo estão caindo, então o resultado geral é baixo, não?
Shahbaz 26/09
@ Shahbaz, meu mal, é claro que o ônibus será conectado - e eu consertei a resposta. Se você quiser cabear - ou, apenas inverta as polaridades (mestre puxa fracamente, escravos puxam fortemente).
avakar
Lendo na wikipedia, percebi que eles se referem a ele como com fio - e ou com fio - ou com lógica negativa-verdadeira.
Shahbaz 26/09
1

Eu sugeriria ter um pull-up ou pull passivo no ônibus (eu assumirei pull-up), e ter escravos ativamente dirigindo o ônibus (dirigindo alto e baixo) quando eles têm algo a dizer e o flutuam de outra forma . Tenha comandos de endereço de consulta que recebem um endereço e uma máscara e instruem cada escravo a produzir 00 ou não fazer nada (continue flutuando sua saída) com base no fato de gostar do endereço e da máscara. Se possível, peça ao mestre que conduza o ônibus ativamente alto algum tempo antes de os escravos começarem a dirigi-lo. Dependendo da força da tração e se o mestre conduz o barramento alto, antes que os escravos possam puxá-lo para baixo, pode ser necessário limitar a velocidade do barramento durante a fase de configuração. Por outro lado, quando a instalação estiver concluída,

supercat
fonte
Se dois escravos dirigem ativamente alto e baixo, o que devo ler do ônibus?
Shahbaz 26/09
Deve-se evitar que um escravo tente dirigir alto enquanto outro está dirigindo baixo. Um escravo só deve dirigir o ônibus quando: (1) sabe que será a única coisa que faz isso; ou (2) sabe que ele e todos os outros que estão dirigindo o ônibus o conduzirão para o oposto de sua marcha passiva Estado.
Supercat 26/09/13
O que isso significa então? ... tendo cada escravo seleccionado dirigir activamente tanto elevado e níveis baixos vai permitir que o barramento para ...
Shahbaz
@ Shahbaz: Quando um escravo tem algo a dizer, ele deve ativar ativamente o barramento alto para transmitir bits "1" e baixo para transmitir bits "0". Quando um escravo não tem nada a dizer, não deve dirigir o ônibus. Observe que ter escravos dirigindo ativamente o barramento alto quando desejam enviar bits "1" permitirá que o barramento opere muito mais rápido do que dependeria de uma tração passiva para elevar o barramento.
Supercat 26/09/2013
@ Shahbaz: O que o supercat está tentando dizer é que, no estado de enumeração, um resistor deve puxar a linha e os escravos devem enviar apenas "0" ou nada (saída de dreno aberto), mas depois, em comunicação normal, apenas um um escravo único deve estar ativo de cada vez e o escravo ativo deve enviar "0" ou "1" (saída normal). Assim, o resistor de pull-up e a capacitância da linha limitam apenas a taxa de bits durante a enumeração. Posteriormente, na comunicação normal, a taxa de bits pode ser maior, conforme permitido pela direção ativa.
Laszlo Valko 26/09