AnsweredAssumed Answered

Error while sending stop condition for I2c

Question asked by A2 on Jun 26, 2013
Latest reply on Jul 13, 2013 by knik
I have made code for I2c master mode tx. Problem is when stop condition is sent & contro; comes out of bold line in the code, tx_idx get the value 9. However it should be 7 , as I am sending 7 bytes only.

void I2C3_ER_IRQHandler(void)
{
    if( (I2C3->SR1 & 0xff00) != 0x00 )        /* then one of error flag is set       */
    {
        I2C3->SR1 &= 0x00FF;                  /* Clears error flags                  */
        i2c_err = 1;                          /* set the flag that error has occured */
    }    
    
}


void I2C3_EV_IRQHandler(void)
{
    uint32_t flag1;
    uint32_t flag2;
    uint32_t event;
    
    
    if( master_rx_tx == 0 )
    {
    /* read flag first */
        flag1 = I2C3->SR1;                 /* read SR1 */
        flag2 = I2C3->SR2;                 /* read SR2 */
        flag2 = flag2 << 16;               
        event = ( flag1 | flag2 ) & 0x00ffffff;  /* upper bits are cleared as they are reserved */
        
        switch(event)
        {
            case I2C_EVENT_MASTER_MODE_SELECT :    /* EV5, this get set after start condition transmitted successfully, ---*/
                                                   /* --- bus is free & master mode is selected */
                I2C3->DR = RTC_ADD ;               /* Send RTC address */
                tx_idx++;
            break;
            
     
            case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED :  /* Check on EV6, BUSY, MSL, ADDR, TXE and TRA flags */
                I2C3->DR = tx_buffer[tx_idx++] ;               /* Transmit the First Data, after address  */         
            break;   
            
            
            case I2C_EVENT_MASTER_BYTE_TRANSMITTING:  /* EV8 , TRA, BUSY, MSL, TXE flags  */
            case I2C_EVENT_MASTER_BYTE_TRANSMITTED:   /* EV8_2, TRA, BUSY, MSL, TXE and BTF flags  */
                if( tx_idx == 7 )                     /* send stop condition */
                {
                    I2C3->CR1 |= I2C_CR1_STOP;        /* generate a stop condition */
                    tx_idx++;
                    stop_sent = 1;
                }    
                else
                {
                    I2C3->DR = tx_buffer[tx_idx++] ;               /* Transmit the data  */     
                }    
            break;
            
            
            default :
            break;
            


        } /* switch ends here */
        
    }
    else   /*  its in receiver mode */
    {
        if( I2C3->SR1 & 0x01 )                /* if start condition is generated  */
        {


        }    
        


    }    
    


    
}




int main(void)
{
/* configure rtc */
    config_rtc();
    



/* transmit data */
    i2c_err = 0;
    no_byte_transmit = 9;
    tx_idx = 0;
    master_rx_tx = 0;
    timeout = 100;
    stop_sent = 0;
    tx_buffer[0] = RTC_ADD;
    tx_buffer[1] = 0x02; tx_buffer[2] = 0x02; tx_buffer[3] = 0x02;
    tx_buffer[4] = 0x02; tx_buffer[5] = 0x02; tx_buffer[6] = 0x02;
    
    I2C3->CR1 |= I2C_CR1_START;    /* generate start condition */
    





    while( stop_sent == 0 );


    configure_tim3_wait(10000); 
    
/* now receive */
    tx_idx = 0;
    rx_idx = 0;
    no_byte_transmit = 3;
    no_byte_receive  = 7;


    while(1);  


} /* function ends here */








void config_rtc(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
/* I2C Peripheral clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE);    


/* SDA GPIO clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  
/*SCL GPIO clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);    


/* Reset I2C3  */
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C3, ENABLE);
  
/* Release reset signal of I2C3  */
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C3, DISABLE);
   
/*Configure I2C SCL pin */
    GPIO_InitStructure.GPIO_Pin    = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType  = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd   = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);    
    /*Configure GPIO pin alternate function */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_I2C3);


/*Configure I2C SDA pin */
    GPIO_InitStructure.GPIO_Pin    = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType  = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd   = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStructure);    
    /*Configure GPIO pin alternate function */
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_I2C3);


/* Configure the I2C event priority */
    NVIC_InitStructure.NVIC_IRQChannel                   = I2C3_EV_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


/* Configure I2C error interrupt priority */
    NVIC_InitStructure.NVIC_IRQChannel                   = I2C3_ER_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


/* I2C De-initialize */
    I2C_DeInit(I2C3);
    
/* configure I2c registers */
    I2C3->CR1    &= (uint16_t)~((uint16_t)I2C_CR1_PE);     /* disable peripheral first                                   */
    I2C3->CR2     = (uint16_t)0x001E;                      /* Disable dma, disable interrupts , set freq equal to 30mhz  */ 
    I2C3->TRISE   = (uint16_t)0x000A;                      /* configure max rise time of 300ns in fast mode              */
    I2C3->CCR     = (uint16_t)0x801A;                      /* fast mode , T low/T high = 2 , CCR[11:0] = 0x15 = 26    ---*/
                                                           /* ---Tlow = 2 * 26/30Mhz = 1.7us , Thigh = Tlow/2 = 0.8us    */    
    I2C3->CR1    |=  (uint16_t)0x0400;                     /* ack returned after byte reception, i2c mode                */
    I2C3->OAR1    =  (uint16_t)(0x4000 | RTC_ADD);         /* write RTC address here                                     */
    I2C_ITConfig(I2C3, I2C_IT_ERR , ENABLE);               /* enable RTC error interrupts                                */
    I2C_ITConfig(I2C3, (I2C_IT_EVT | I2C_IT_BUF), ENABLE); /* enable buffer & event interrupts                           */
    I2C3->CR1    |= I2C_CR1_PE;                            /* enable peripheral I2c                                      */


} /* function ends here */

Outcomes