I2C no puede leer desde FT201XS

0

Estoy usando un microcontrolador de ciprés para leer algunos valores del chip FT201XS-R. Puedo obtener reconocimiento, pero parece que no puedo leer. Aquí está la hoja de datos . Estoy intentando leer el registro 4 de la memoria MTP como se describe en la página 39 de la hoja de datos.

Aquí está mi código

int main{

    uint8 addr = 0x22;
    uint8 WriteBuffer[16];



    UART_1_Start();

// I added this because the I2C will be pulled low by a slave when addressing goes wrong. This helps to make it still work
    while(I2C_1_sda_Read() == 0) // SDA hang low
    {
        I2C_1_SET_I2C_SCL_HSIOM_SEL(I2C_1_HSIOM_GPIO_SEL); //Switch to GPIO    
        I2C_1_scl_Write(0);
        CyDelay(1);
        I2C_1_scl_Write(1);
        CyDelay(1);
        I2C_1_SET_I2C_SCL_HSIOM_SEL(I2C_1_HSIOM_I2C_SEL); //Switch to Component
    }


    WriteBuffer[0] = 0x10; // this is the address mtp signal
    status = i2c_send(0x00,WriteBuffer,1u);

    WriteBuffer[0] = 0x00;
    WriteBuffer[1] = 0x04; // this is register 4
    status = i2c_send(addr,WriteBuffer,2);

    WriteBuffer[0] = 0x14; // this is the mtp register read value
    status = i2c_send(0x00,WriteBuffer,1u);
    readData = i2c_recieve(addr);

}

uint32 i2c_send(uint8 addr, uint8 * data, uint8 count){
    uint32 status=1;
    uint8 i =0;
    uint8 check;
    I2C_1_I2CMasterClearStatus();
    status = I2C_1_I2CMasterSendStart(addr, 0u);
    while(status){
        I2C_1_I2CMasterClearStatus();
        I2C_1_I2CMasterSendStop();
        CyDelay(10);
        status = I2C_1_I2CMasterSendStart(addr, 0u);
    }

    for (;i<count;i++){
        check = *(data+i);
       status = I2C_1_I2CMasterWriteByte(*(data+i)); 
    }

    I2C_1_I2CMasterSendStop();
    CyDelay(10);
    return status;


}

uint8 i2c_recieve(uint8 addr){
    uint32 status;
    uint32 readData;
    CyDelay(10);
    status = I2C_1_I2CMasterSendStart(addr, I2C_1_I2C_READ_XFER_MODE);
    while(status){
        I2C_1_I2CMasterClearStatus();
        I2C_1_I2CMasterSendStop();
        CyDelay(10);
        status = I2C_1_I2CMasterSendStart(addr, I2C_1_I2C_READ_XFER_MODE);
    }
    readData= I2C_1_I2CMasterReadByte(I2C_1_I2C_NAK_DATA);
    I2C_1_I2CMasterSendStop();
    return readData;


}

Puedo hacer todos los comandos de envío de I2C, pero cuando intento hacer una recepción de I2C, el estado se bloquea en 2, que es el error SCB_I2C_MSTR_NOT_READY. Esto corresponde a esta descripción:

  

El maestro no está listo para iniciar la transferencia. Un maestro todavía no tiene   transacción anterior completada o una operación esclava está en curso (en   configuración multi-maestro-esclavo). Nada fue enviado en el autobús. los   intento debe ser reintentado.

¿Qué debo cambiar para que el registro se lea para que funcione?

EDITAR ***************

Creé una nueva función para realizar la lectura

uint32 i2c_read_mem(uint8 addr, uint8 reg){
    uint32 status=1;
    uint32 readData;
    uint8 i =0;
    uint8 check;



    status = I2C_1_I2CMasterSendStart(0x00, 0);
    status = I2C_1_I2CMasterWriteByte(0x10);
    status = I2C_1_I2CMasterSendRestart(addr,0);
    status = I2C_1_I2CMasterWriteByte(0x00);
    status = I2C_1_I2CMasterWriteByte(reg);
    status = I2C_1_I2CMasterSendRestart(0x00,0);
    status = I2C_1_I2CMasterWriteByte(0x14);
    status = I2C_1_I2CMasterSendRestart(addr,1);
    readData= I2C_1_I2CMasterReadByte(I2C_1_I2C_ACK_DATA);
    I2C_1_I2CMasterSendStop();
    return readData;


}

Con esta función, I2C ya no se bloquea, pero siempre devuelve 0. Según este documento , debería ver el video usb en los bytes 2 y 3. pero cuando ejecuto

for (i=0; i<20; i++){
        readData = i2c_read_mem(addr, i);
        CyDelay(1);
}

todos los valores devueltos son 0.

    
pregunta Legen Diary

1 respuesta

1

La hoja de datos muestra un reinicio de I2C entre la fase (comando general de llamada + dirección MTP) y la fase (bytes de dirección esclavo + MTP), y nuevamente entre el (comando general de transferencia + transferencia MTP) y los bytes (esclavo + datos ), pero su código realiza una parada y luego un inicio en cada uno de estos casos.

Su capa de abstracción es demasiado alta, necesita usar las acciones I2C de bajo nivel para esto, o bien, agregue un parámetro a i2c_send para inhibir la acción STOP al final.

    
respondido por el Ben Voigt

Lea otras preguntas en las etiquetas