classe I2CTarget – um dispositivo alvo I2C¶
Um alvo I2C é um dispositivo que se liga a um barramento I2C e é controlado por um controlador I2C. Os alvos I2C podem assumir diversas formas. A classe machine.I2CTarget implementa um alvo I2C que pode ser configurado como um dispositivo de memória/registos, ou como um dispositivo I2C arbitrário usando callbacks (se suportado pela porta).
Disponível nas OpenMV Cam M4 / M7 / H7 / H7 Plus / Pure Thermal / RT1062 / AE3.
Exemplo de utilização para o caso de um dispositivo de memória:
from machine import I2CTarget
# Create the backing memory for the I2C target.
mem = bytearray(8)
# Create an I2C target. Depending on the port, extra parameters
# may be required to select the peripheral and/or pins to use.
i2c = I2CTarget(addr=67, mem=mem)
# At this point an I2C controller can read and write `mem`.
...
# Deinitialise the I2C target.
i2c.deinit()
Note que algumas portas requerem que um id, e possivelmente pinos scl e sda, sejam passados ao construtor I2CTarget, para selecionar a instância de hardware I2C e os pinos a que se liga.
Quando configurado como dispositivo de memória, é também possível registar-se para receber eventos. Por exemplo, para ser notificado quando a memória é lida/escrita:
from machine import I2CTarget
# Define an IRQ handler, for I2C events.
def irq_handler(i2c_target):
flags = i2c_target.irq().flags()
if flags & I2CTarget.IRQ_END_READ:
print("controller read target at addr", i2c_target.memaddr)
if flags & I2CTarget.IRQ_END_WRITE:
print("controller wrote target at addr", i2c_target.memaddr)
# Create the I2C target and register to receive default events.
mem = bytearray(8)
i2c = I2CTarget(addr=67, mem=mem)
i2c.irq(irq_handler)
Dispositivos I2C mais complexos podem ser implementados usando o conjunto completo de eventos. Por exemplo, para ver os eventos em bruto à medida que são despoletados:
from machine import I2CTarget
# Define an IRQ handler that prints the event id and responds to reads/writes.
def irq_handler(i2c_target, buf=bytearray(1)):
flags = i2c_target.irq().flags()
print(flags)
if flags & I2CTarget.IRQ_READ_REQ:
i2c_target.write(buf)
if flags & I2CTarget.IRQ_WRITE_REQ:
i2c_target.readinto(buf)
# Create the I2C target and register to receive all events.
i2c = I2CTarget(addr=67)
all_triggers = (
I2CTarget.IRQ_ADDR_MATCH_READ
| I2CTarget.IRQ_ADDR_MATCH_WRITE
| I2CTarget.IRQ_READ_REQ
| I2CTarget.IRQ_WRITE_REQ
| I2CTarget.IRQ_END_READ
| I2CTarget.IRQ_END_WRITE
)
i2c.irq(irq_handler, trigger=all_triggers, hard=True)
Construtores¶
- class machine.I2CTarget(id: int, addr: int, *, addrsize: int = 7, mem: bytearray | None = None, mem_addrsize: int = 8, scl: Pin | None = None, sda: Pin | None = None)¶
Constrói e devolve um novo objeto I2CTarget usando os seguintes parâmetros:
id identifica um periférico I2C específico. Os valores permitidos dependem da porta/placa em particular. Algumas portas têm um valor predefinido, caso em que este parâmetro pode ser omitido.
addr é o endereço I2C do alvo.
addrsize é o número de bits no endereço do alvo I2C. Os valores válidos são 7 e 10.
mem é um objeto com o protocolo buffer que seja gravável. Se não for especificado, não existe memória de suporte e os dados devem ser lidos/escritos usando os métodos
I2CTarget.readinto()eI2CTarget.write().mem_addrsize é o número de bits no endereço de memória. Os valores válidos são 0, 8, 16, 24 e 32.
scl é um objeto pino que especifica o pino a usar para SCL.
sda é um objeto pino que especifica o pino a usar para SDA.
Note que algumas portas/placas terão valores predefinidos de scl e sda que podem ser alterados neste construtor. Outras terão valores fixos de scl e sda que não podem ser alterados.
Métodos Gerais¶
- deinit() None¶
Desinicializa o alvo I2C. Após a chamada deste método, o hardware deixará de responder a pedidos no barramento I2C e nenhum outro método pode ser chamado.
- readinto(buf: bytearray) int¶
Lê para o buffer fornecido os bytes pendentes escritos pelo controlador I2C. Devolve o número de bytes lidos.
- write(buf: bytes) int¶
Escreve os bytes do buffer fornecido, para serem passados ao controlador I2C após este enviar um pedido de leitura. Devolve o número de bytes escritos. A maioria das portas apenas aceita um byte de cada vez neste método.
- irq(handler: Callable[[I2CTarget], None] | None = None, trigger: int = IRQ_END_READ | IRQ_END_WRITE, hard: bool = False) None¶
Instala um
handlerIRQ que é invocado quando um dos eventos selecionados portriggeré despoletado.triggeré uma máscara de bits das constantesIRQ_*combinadas com OR; o predefinido dispara no fim de cada leitura ou escrita do lado do controlador.hard=Trueregista um handler de interrupção hard (sem alocação de heap no callback). O predefinido é um callback agendado. Passehandler=Nonepara desativar a interrupção.Nota
IRQ_ADDR_MATCH_READ,IRQ_ADDR_MATCH_WRITE,IRQ_READ_REQeIRQ_WRITE_REQdevem ser tratados por um callback de IRQ hard (hard=True) porque os eventos têm de ser reconhecidos sincronamente com o hardware.IRQ_END_READeIRQ_END_WRITEpodem ser tratados por callbacks soft ou hard; todos os eventos partilham um único handler, por isso se algum evento precisar de um callback hard, todos precisam.Quando um buffer de memória é fornecido ao construtor, o driver suprime
IRQ_END_WRITEpara a transação que apenas escreve o endereço de memória. Isto mantém os eventos de fim de transação significativos mesmo quando o agendador soft-IRQ adia o callback.
- memaddr¶
O valor inteiro do endereço de memória mais recente que foi selecionado pelo controlador I2C (apenas válido se
memfoi especificado no construtor).
Constantes¶
Cada constante
IRQ_*é um bit de flag. Combine-as com OR para construir uma máscaratriggerparairq(). Dentro do handler, o conjunto de eventos disparados pode ser recuperado viaself.irq().flags()com AND aplicado a cada constante.- IRQ_ADDR_MATCH_READ: int¶
Dispara quando um controlador endereça este alvo para uma transação de leitura (o byte de endereço foi recebido com o bit leitura/escrita a
1). Apenas Hard-IRQ.
- IRQ_ADDR_MATCH_WRITE: int¶
Dispara quando um controlador endereça este alvo para uma transação de escrita (o byte de endereço foi recebido com o bit leitura/escrita a
0). Apenas Hard-IRQ.
- IRQ_READ_REQ: int¶
Dispara quando o controlador está a solicitar um byte ao alvo. O handler deve chamar
write()para fornecer o byte antes de o ciclo de relógio do controlador ser concluído. Apenas Hard-IRQ.
- IRQ_WRITE_REQ: int¶
Dispara quando o controlador enviou um byte para o alvo. O handler deve chamar
readinto()para recuperar o byte antes de o controlador enviar o seguinte. Apenas Hard-IRQ.