Clase 8 - Protocolo I2C en Raspberry
Pi
Controlador I2C en Raspberry Pi
• Modo Maestro
• Fast-mode (400Kb/s)
• Direccionamiento de 7 y 10 bits
• Memoria FIFO (First Input – First Output)
para TX y RX de 16 bytes
• Tres/ocho controladores I2C
• Ocho registros de 32 bits
Controladores
• BSC0 (0x0020_5000)
• BSC1 (0x0080_4000)
• BSC2 (0x0080_5000) @HDMI
• BSC3 (0x0080_5600) @RPI4
• BSC4 (0x0080_5800) @RPI4
• BSC5 (0x0080_5A80) @RPI4
• BSC6 (0x0080_5C00) @RPI4
• BSC7 (0x0080_5??0) @RPI4 @HDMI
Registros
• C, Control @0x00
• S, Status @0x04
• DLEN, Data length @0x08
• A, Slave Address @0x0C
• FIFO, Data FIFO @0x10
• DIV, Clock Divider @0x14
• DEL, Data Delay @0x18
• CLKT, Clock Stretch Timeout @0x1C
Configuración de GPIO para I2C
• Registro GPFSELx en función alternativa
– SDA0 GPIO0 (ALT0)
– SCL0 GPIO1 (ALT0)
– SDA1 GPIO2 (ALT0)
– SCL1 GPIO3 (ALT0)
–⋮
Configuración de GPIO para I2C
Reloj del Controlador I2C
• Protocolo I2C es síncrono
• ¿Quién establece la frecuencia de la
señal de reloj?
– Reloj del Core
• Problema:
– Es variable por defecto
Modificar Reloj del Core
• vcgencmd measure_clock [clock]
vcgencmd measure_clock core
*Ejecutar en terminal
Modificar Reloj del Core
• sudo mousepad /boot/[Link]
• Añadir las líneas
– core_freq=250
– core_freq_min=250
• *250 MegaHertz
Modificar Reloj del Core
Registro de Control
Registro de Control
Configuración del I2C
• Configurar GPIOx como SDA y SCL con
GPFSELn
• Habilitar I2Cx con el bit I2CEN (bit 15)
– bitset(C,15);
• Deshabilita interrupciones
– bitclr(C,10); // Deshabilita INTR de registro C
– bitclr(C,9); // Deshabilita INTT de registro C
– bitclr(C,8); // Deshabilita INTD de registro C
Configuración del I2C
• Limpiar FIFO
– C |= 0x00000030;
• Establecer Frecuencia de reloj
– DIV = CORE_FREQ/FSCL
– Donde FSCL es la frecuencia deseada
• 100000 // 100 Kilo bits per second
• 400000 // 400 Kilo bits per second
– CORE_FREQ= 250000000 es la frecuencia
establecida anteriormente (250MHz)
Modo Escritura
1. Escribir la dirección del esclavo en A
2. Limpiar FIFO con C = 0x00000030
3. Escribir el numero de bytes a transmitir en
DLEN
4. Escribir los bytes a transmitir en FIFO
5. [Link] = 0, C.I2CEN = 1 y [Link] = 1
6. Esperar hasta que [Link] == 1
7. Verificar banderas [Link], [Link],
[Link]
Modo Lectura
• Escribir la dirección del esclavo en A
• Limpiar FIFO con C = 0x00000030
• Escribir 1 en DLEN
• Escribir en FIFO la dirección del registro a leer
• [Link] = 0, C.I2CEN = 1 y [Link] = 1
• Esperar hasta que [Link] == 1
• Escribir el número de bytes a leer en DLEN
• Establecer [Link] = 1 y [Link] = 1
• Esperar hasta que [Link] == 1
• Leer los datos de FIFO uno a uno
• Verificar banderas [Link], [Link], [Link]