0
\$\begingroup\$

I am trying to communicate with a battery using SMBUS. Battery has 2 sections so it uses 2 separate SMBUS lines. I am trying to read SOC information from two section by using STM32F103C8. First communication is successful but second one fails all the time. So it is like this: If I use hi2c1 first then it is successful but hi2c2 fails. If I use hi2c2 first then it is successful but hi2c1 fails.That made me think the circuitry is okay. What can be the reason for it? Here is the related parts of the code that I am using:

int getBatterySOC(I2C_HandleTypeDef *batteryI2CHardwareHandle){
    memset (smbusData,0x00,16);
    smbusData[0] = SMBBUS_GET_RELATIVE_SOC_COMMAND;
    if (HAL_OK != HAL_I2C_Master_Transmit(batteryI2CHardwareHandle,(uint8_t)BATTERY_SMBUS_SLAVE_ADDRESS,smbusData,2,1000)){

        return -1;

    }

    if (HAL_OK != HAL_I2C_Master_Receive(batteryI2CHardwareHandle,(uint8_t)BATTERY_SMBUS_SLAVE_ADDRESS + 1 , smbusData,1,1000)){

        return -1;

    }

    return smbusData[0];

}

int main(void)
{
    /* USER CODE BEGIN 1 */
    currentDischargerState = DS_INITIALIZING;
    memset(USBreceiveBuffer,0x00, USB_RECEIVE_BUFFER_SIZE);
    receivedUSBLine = 0;
    USBreceivedLength = 0;

    /* USER CODE END 1 */

    /* MCU Configuration----------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();


    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */
    //Initialise the clocks before the I2C inits.
    __HAL_RCC_I2C1_CLK_ENABLE();
    __HAL_RCC_I2C2_CLK_ENABLE();
    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_I2C1_Init();
    MX_I2C2_Init();
    MX_TIM2_Init();
    MX_TIM3_Init();
    MX_TIM4_Init();
    /* USER CODE BEGIN 2 */
    //Set Beginning Discharge Power to 0.
    user_pwm_setvalue(9999,&htim2,TIM_CHANNEL_1);
    user_pwm_setvalue(9999,&htim3,TIM_CHANNEL_1);
    HAL_Delay(100);
    //  I2C_Errate_Workaround(1);
    //  I2C_Errate_Workaround(2);

    /* USER CODE END 2 */

    /* USER CODE BEGIN RTOS_MUTEX */
    /* add mutexes, ... */
    /* USER CODE END RTOS_MUTEX */

    /* USER CODE BEGIN RTOS_SEMAPHORES */
    /* add semaphores, ... */
    /* USER CODE END RTOS_SEMAPHORES */

    /* USER CODE BEGIN RTOS_TIMERS */
    /* start timers, add new ones, ... */
    /* USER CODE END RTOS_TIMERS */

    /* Create the thread(s) */
    /* definition and creation of defaultTask */
    osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
    defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

    /* definition and creation of LedTask */
    osThreadDef(LedTask, StartLedTask, osPriorityIdle, 0, 128);
    LedTaskHandle = osThreadCreate(osThread(LedTask), NULL);

    /* definition and creation of SMBUSTask */
    osThreadDef(SMBUSTask, StartSMBUSTask, osPriorityIdle, 0, 128);
    SMBUSTaskHandle = osThreadCreate(osThread(SMBUSTask), NULL);

    /* definition and creation of FanControlTask */
    osThreadDef(FanControlTask, StartFanControlTask, osPriorityIdle, 0, 128);
    FanControlTaskHandle = osThreadCreate(osThread(FanControlTask), NULL);

    /* USER CODE BEGIN RTOS_THREADS */
    /* add threads, ... */
    /* USER CODE END RTOS_THREADS */

    /* USER CODE BEGIN RTOS_QUEUES */
    /* add queues, ... */
    /* USER CODE END RTOS_QUEUES */

    /* Start scheduler */
    osKernelStart();

    /* We should never get here as control is now taken by the scheduler */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {

        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */

    }
    /* USER CODE END 3 */

}

static void MX_I2C1_Init(void)
{

    hi2c1.Instance = I2C1;
    hi2c1.Init.ClockSpeed = 15000;
    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
    if (HAL_I2C_Init(&hi2c1) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }

}

/* I2C2 init function */
static void MX_I2C2_Init(void)
{

    hi2c2.Instance = I2C2;
    hi2c2.Init.ClockSpeed = 15000;
    hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
    hi2c2.Init.OwnAddress1 = 0;
    hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c2.Init.OwnAddress2 = 0;
    hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
    if (HAL_I2C_Init(&hi2c2) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }

}

void StartSMBUSTask(void const * argument)
{
    /* USER CODE BEGIN StartSMBUSTask */
    /* Infinite loop */
    for(;;)
    {
        int receivedSOC;

        receivedSOC = getBatterySOC(&hi2c2);
        if (receivedSOC != -1 && receivedSOC<=100){
            socBattery2 = receivedSOC;
        }
        else{

            //HAL_I2C_DeInit(&hi2c1);
            //HAL_I2C_Init(&hi2c1);
            //RCC -> APB1ENR |= 0b1 <<21;
            //RCC-> APB1RSTR |= 0b1 <<21;
            //MX_I2C1_Init();

            memset (statusString,0x00,255);
            statusStringLength = sprintf(statusString,"I2C Transmit FAIL \r\n");
            CDC_Transmit_FS(statusString,statusStringLength);

        }


        osDelay(5000);


            receivedSOC = getBatterySOC(&hi2c1);
            if (receivedSOC != -1 && receivedSOC<=100){
                socBattery1 = receivedSOC;
            }
            else{
                //RCC -> APB1ENR |= 0b1 <<22;
                //RCC-> APB1RSTR |= 0b1 <<22;
            //  MX_I2C2_Init();
                memset (statusString,0x00,255);
                            statusStringLength = sprintf(statusString,"I2C Transmit FAIL \r\n");


            }




        osDelay(5000);
    }
    /* USER CODE END StartSMBUSTask */
}
\$\endgroup\$
0
\$\begingroup\$

Could be, that other tasks are interrupting your transmit mid-setup (I've had this myself) and your I2C bus remains locked and semi-configured. Try surrounding your I2C commands in taskENTER_CRITICAL() and taskEXIT_CRITICAL() to prevent other tasks interrupting. More info here

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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