ciaa/firmware_v2

I2C

Opened this issue · 0 comments

Traigo la discusión de los mails:

Martín:

El i2c es uno de los casos mas complejos, pero armar muchos parametros por el hecho de tener una sola funcion, lo unico que hace es trasladar el problema a las inumerables formas de usar el API.

Creo que proveer dos niveles de API i2c es lo mas logico:

Nivel te protocolo:

  • i2c_start(i2c)
  • i2c_stop(i2c)
  • i2c_write(i2c, byte) -> I2C_ACK o I2C_NAK
  • i2c_read(i2c, I2C_ACK o I2C_NAK) -> byte

Hay tres casos de uso de alto nivel en i2c:

  • i2c_send(i2c, addr, data, data_len, I2C_STOP or I2C_CONT)
  • i2c_recv(i2c, addr, data, data_len, I2C_STOP or I2C_CONT)

Con una combinación de ambas, podes armarte el protocolo que haga falta. Si me equivoco, pasame el protocolo extraño y vemos como se solucionaría.

Yo abogo por la simpleza. El terminar una funcion no quiere decir que el core se vuelva inutilizable. Hay que pensar que las funciones i2c sirven para armar protocolos, no son el protocolo en si mismo.
Un caso de uso seria:

i2c_start(I2C0);
i2c_send(I2C0, SLAVE_ADDR | I2C_WR, I2C_WITH_ACK) && die("I2C no ack sending command");
i2c_send(I2C0, low_addr, I2C_WITH_ACK) && die("I2C no ack sending addr low");
i2c_send(I2C0, high_addr, I2C_WITH_ACK) && die("I2C no ack sending addr high");
i2c_recv(I2C0, &data0, I2C_WITH_ACK) && die("I2C no ack on data0 read");
i2c_recv(I2C0, &data1, I2C_WITH_ACK) && die("I2C no ack on data1 read");
i2c_recv(I2C0, &data2, I2C_WITH_ACK) && die("I2C no ack on data2 read");
i2c_recv(I2C0, &data3, I2C_WITH_ACK) && die("I2C no ack on data3 read");
i2c_stop(I2C0);

Fijate que i2c_send e i2c_recv hacen uso del truco and/or de bash (pero al revez porque retornaira !=0 si anduvo bien, va, si retorna 0 en caso de exito es la misma sintaxis que bash, && para good action, || para bad action)

Eric:

Me gusta así:

Nivel te protocolo:

  • i2cStart( i2c );
  • i2cStop( i2c );
  • i2cMasterWrite( i2c, byte ) -> I2C_ACK o I2C_NAK
  • i2cMasterRead( i2c, I2C_ACK o I2C_NAK ) -> byte
  • i2cSlaveWrite( i2c, I2C_ACK o I2C_NAK ) -> byte <ver parámetros>
  • i2cSlaveRead( i2c, byte ) -> I2C_ACK o I2C_NAK <ver parámetros>

Casos de uso de alto nivel en i2c (modo Master):

  • i2cWrite( i2c, addr, data, dataLen, I2C_STOP or I2C_CONT )
  • i2cRead( i2c, addr, data, dataLen, I2C_STOP or I2C_CONT )

Falta el config/init:

  • i2cMasterConfig( i2c, addressSize <7, 8 o 10 bits>, clock )
  • i2cSlaveConfig( )

¿dataLen, o dataSize? ¿qué prefieren?