0
\$\begingroup\$

void I2C_Config(void) { I2C_InitTypeDef I2C_InitStructure;

I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_Timing = (PRESC << 28) | (SCLDEL << 20)
        | (SDADEL << 16) | (SCLH << 8) | SCLL;      // 100kHz
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;      // I2C mode
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; // enable acknowledge when reading (can be changed later on)
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses
I2C_Init(I2C_PERIPH, &I2C_InitStructure);       // init I2C peripheral
I2C_Cmd(I2C_PERIPH, ENABLE);

}

void I2C_HW_tx(uint8_t i2cAddr, uint8_t *dataTx, uint8_t length, uint8_t stopOrNotWhenSent) {

if (stopOrNotWhenSent == STOP_WHEN_SENT) {
    I2C_TransferHandling(I2C_PERIPH, i2cAddr, 1, I2C_Reload_Mode,
    I2C_Generate_Start_Write);
    PRINTF("\nI2C_tx - 1\n");
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXIS) == RESET)
        ;
    PRINTF("\nI2C_tx - 2\n");
    for (uint8_t i = 0; i < length - 1; i++) {
        I2C_SendData(I2C_PERIPH, *(dataTx + i));
        while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TCR) == RESET)
            ;
        PRINTF("\nI2C_tx - 3\n");
    }
    I2C_AutoEndCmd(I2C_PERIPH, ENABLE);
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXIS) == RESET)
        ;
    I2C_SendData(I2C_PERIPH, *(dataTx + length - 1));
    I2C_ReloadCmd(I2C_PERIPH, DISABLE);
} else {
    I2C_TransferHandling(I2C_PERIPH, i2cAddr, length, I2C_SoftEnd_Mode,
    I2C_Generate_Start_Write);
    PRINTF("\nI2C_tx - 1\n");
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXIS) == RESET)
        ;
    PRINTF("\nI2C_tx - 2\n");
    for (uint8_t i = 0; i < length; i++) {
        I2C_SendData(I2C_PERIPH, *(dataTx + i));
        while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TC) == RESET)
            ;
        PRINTF("\nI2C_tx - 3\n");
    }
}
if (stopOrNotWhenSent == STOP_WHEN_SENT) {
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_STOPF) == RESET)
        ;
    I2C_ClearFlag(I2C_PERIPH, I2C_FLAG_STOPF);
}
PRINTF("\nI2C_tx - 4\n");

}

void I2C_HW_rx(uint8_t i2cAddr, uint8_t *dataRx, uint8_t length) {

PRINTF("\nI2C_rx - 1\n");
I2C_TransferHandling(I2C_PERIPH, i2cAddr, length, I2C_AutoEnd_Mode,
I2C_Generate_Start_Read);

for (uint8_t i = 0; i < length; i++) {
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_RXNE) == RESET)
        ;
    PRINTF("\nI2C_rx - 2\n");
    *(dataRx + i) = I2C_ReceiveData(I2C_PERIPH);
}
while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_STOPF) == RESET)
    ;
PRINTF("\nI2C_rx - 3\n");
I2C_ClearFlag(I2C_PERIPH, I2C_FLAG_STOPF);

}

I read bytes from MCP4728 using I2C_HW_rx with success. The problem is with I2C_HW_tx - it halts when trying to send:

uint8_t dataTx[8];
for (uint8_t i = 0; i < 4; i++) {
    *(dataTx + i * 2) =
            FASTWRITE
                    | (((channelData->powerMode << 4)
                            | (channelData->dacValue >> 8)) & 0x3F);
    *(dataTx + i * 2 + 1) = channelData->dacValue & 0xFF;
    if (i < 3) {
        channelData++;
    }
}
I2C_HW_tx(DEVICE_CODE | (mcp4728WholeData[mcp4728Id].currI2CAddr << 1),
        dataTx, 8, STOP_WHEN_SENT);

}

So my question to You - how to send multiple bytes by STM32F0 (master) to I2C bus, using StdPeriphLibrary? I was searching in Google, but the few examples with StdPeriphLibrary for STM32F0 are with sending I2Caddr, register and value (three bytes), but I need to send for example I2Caddr and ten bytes.

\$\endgroup\$
0
\$\begingroup\$

OK i managed with this problem - checking of TCR flag in loop was mistake. The working code is below:

void I2C_HW_tx(uint8_t i2cAddr, uint8_t *dataTx, uint8_t length, uint8_t stopOrNotWhenSent) {

if (stopOrNotWhenSent == STOP_WHEN_SENT) {
    I2C_TransferHandling(I2C_PERIPH, i2cAddr, length,
    I2C_AutoEnd_Mode,
    I2C_Generate_Start_Write);
    //PRINTF("\nI2C_tx - 1\n");
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXIS) == RESET)
        ;
    //PRINTF("\nI2C_tx - 2\n");
    for (uint8_t i = 0; i < length; i++) {
        while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXE) == RESET)
            ;
        I2C_SendData(I2C_PERIPH, *(dataTx + i));
        //PRINTF("\nI2C_tx - 3\n");
    }
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_STOPF) == RESET)
        ;
    I2C_ClearFlag(I2C_PERIPH, I2C_FLAG_STOPF);
} else {
    I2C_TransferHandling(I2C_PERIPH, i2cAddr, length, I2C_SoftEnd_Mode,
    I2C_Generate_Start_Write);
    //PRINTF("\nI2C_tx - 1\n");
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXIS) == RESET)
        ;
    //PRINTF("\nI2C_tx - 2\n");
    for (uint8_t i = 0; i < length; i++) {
        while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXE) == RESET)
            ;
        I2C_SendData(I2C_PERIPH, *(dataTx + i));
        //PRINTF("\nI2C_tx - 3\n");
    }
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TC) == RESET)
        ;
    //PRINTF("\nI2C_tx - 4\n");
}
//PRINTF("\nI2C_tx - 5\n");

}

The one thing that I don't know how to do is WriteI2CAddress to MCP4728 slave device (http://ww1.microchip.com/downloads/en/DeviceDoc/22187E.pdf - page 42). LDAC line should become low from high state during 8th bit of command. Do you know how to do it using hardware I2C in STM32?

\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.