cancel
Showing results for 
Search instead for 
Did you mean: 

I2C slave clock stretching

kyc
Associate II
Posted on July 21, 2014 at 09:43

Hi everyone I am Khai.

Currently I am working with STM32F103ZE. I would like to test on clock stretching by using a delay()-function. But seems like it doesn't work. Any advice or suggestion on how to make a test for clock stretching?

Belows are my written code:

INIT

void I2C_Initi (I2C_TypeDef *i2cx, int OwnAddress, I2C_Callback_t *callWr, I2C_Callback_t *callRd) {

    I2C_InitTypeDef  I2C_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

    uint32_t clock_en;

    callbackWr = callWr;

    callbackRd = callRd;

    switch((unsigned int)i2cx) {

    case (unsigned int)I2C1: clock_en = RCC_APB1Periph_I2C1; break;

    case (unsigned int)I2C2: clock_en = RCC_APB1Periph_I2C2; break;

    default:

        printf(''I2C_Initi bad i2cx %p'',i2cx );

        return;

        break;

    }

    RCC_APB1PeriphClockCmd(clock_en, ENABLE);

    I2C_StructInit(&I2C_InitStructure);

    I2C_InitStructure.I2C_ClockSpeed = 100000;

    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

    I2C_InitStructure.I2C_OwnAddress1 = OwnAddress;

    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_Init(i2cx, &I2C_InitStructure);

    I2C_ITConfig(i2cx, I2C_IT_BUF|I2C_IT_EVT|I2C_IT_ERR, ENABLE);

    I2C_Cmd(i2cx, ENABLE);

    I2C_StretchClockCmd(i2cx, ENABLE);

    // configure NVIC I2C interrupt

    NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = I2C2_ER_IRQn;

    NVIC_Init(&NVIC_InitStructure);

}

INTERRUPT HANDLER

void I2C2_EV_IRQHandler(void) {

    uint32_t event;

    //I2C_StretchClockCmd(I2C2, ENABLE);

    //delay_us(I2C_Delay);

    event = I2C_GetLastEvent(I2C2);

    switch(event) {

    // sending to MASTER

    case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:

        I2C_SendData(I2C2, i2c_buf_tx[0]);

        tx_count=1;

        break;

    case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:

        I2C_SendData(I2C2, i2c_buf_tx[tx_count]);

        tx_count++;

        if(tx_count>=i2c_send_len-1)

            GPIO_S(gpios+GPO_HOOK_PTT, 0);

        break;

    case I2C_EVENT_SLAVE_ACK_FAILURE:

        /// tell main loop it is done, for example setting i2c_send_len to 0

        if(callbackRd)

            callbackRd(tx_count, (uint8_t*)i2c_buf_tx);

        tx_count=0;

        break;

        // receiving from MASTER

    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:

        I2C_StretchClockCmd(I2C2, ENABLE);

       delay_us(I2C_Delay) ; // delay 20 us

        //i2c_buf_rx[0]=I2C_ReceiveData(I2C2);

        //rx_count=1;

        break;

    case I2C_EVENT_SLAVE_BYTE_RECEIVED:

        delay_us(I2C_Delay); // delay 20 us

        //I2C_StretchClockCmd(I2C2, ENABLE);

        i2c_buf_rx[rx_count]=I2C_ReceiveData(I2C2);

        rx_count++;

        break;

    case I2C_EVENT_SLAVE_STOP_DETECTED:

          delay_us(I2C_Delay); // delay 20 us

        //I2C_StretchClockCmd(I2C2, ENABLE);

        if(callbackWr)

            callbackWr(rx_count, (uint8_t*)i2c_buf_rx);

        I2C_AcknowledgeConfig(I2C2, ENABLE);

        rx_count=0;

        break;

    default:

        err_count++;

        err_event = event;

        break;

    }

    last_event = event;

}

Thank you.

#i2c-stm32
0 REPLIES 0