AnsweredAssumed Answered

STM32F407-WFI problem

Question asked by arunachalam.balas on Aug 29, 2014
I am currently using nordic nRF51822 board and STM32F4 board to send some data using I2C protocol. I am able to send the data from nordic and receive it on STM32F4 board.

Now, I want to put the STM32F4 on sleep mode using __WFI() and wake up when the nordic sends the data. Can you please look into my below code and let me know where I get it wrong. Once the STM32F4 goes to sleep, it never wakes up with the I2C interrupts. void I2C2_EV_IRQHandler(void) is never gets called.

void I2C2_EV_IRQHandler(void)
{
          Event = I2C_GetLastEvent(I2C2 );
          
    switch (Event)
    {
                    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED :
                    {
                              printf("Slave Address Matched\n");
                              break;
                    }
                    case I2C_EVENT_SLAVE_STOP_DETECTED :
                    {
                              printf("Stop Detected\n");
                              I2C2 ->SR1;
                              I2C2 ->CR1 |= 0x1;
                              break;
                    }
    }
}


void I2C2_ER_IRQHandler(void)
{               
          // Read SR1 register to get I2C error 
    if ((I2C_ReadRegister(I2C2, I2C_Register_SR1 ) & 0xFF00) != 0x00)
    {
        // Clears error flags 
        I2C2 ->SR1 &= 0x00FF;
    }
}

void NordicST_I2C2_Initialization()
{
              GPIO_InitTypeDef gpio_init;
            I2C_InitTypeDef i2c_init;
            NVIC_InitTypeDef NVIC_InitStructure;
          NVIC_InitTypeDef NVIC_InitStructure2, NVIC_InitStructure3;
     
              DMA_InitTypeDef  DMA_InitStructure;


    I2C_DeInit(I2C2 );       //Deinit and reset the I2C to avoid it locking up
    I2C_SoftwareResetCmd(I2C2, ENABLE);
    I2C_SoftwareResetCmd(I2C2, DISABLE);


          /*!< I2C Periph clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
     
               /*!< Enable The DMA controller clock */
          RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA1, ENABLE);
          RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA1, DISABLE);
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
    
          /* setup SCL and SDA pins
           * SCL on PB10 and SDA on PB11
           */
    gpio_init.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;         // we are going to use PB10 and PB11
    gpio_init.GPIO_Mode = GPIO_Mode_AF;          // set pins to alternate function
    gpio_init.GPIO_Speed = GPIO_Speed_50MHz;     // set GPIO speed
    gpio_init.GPIO_PuPd = GPIO_PuPd_UP;        //Pull up resistor
    gpio_init.GPIO_OType = GPIO_OType_OD;     //Open Drain
    GPIO_Init(GPIOB, &gpio_init);


          // Connect I2C2 pins to AF  
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2 ); // SCL
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2 ); // SDA
          
               
               
                              // Configure the Priority Group to 1 bit 
                              NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);


                              NVIC_InitStructure2.NVIC_IRQChannel = I2C2_EV_IRQn;
                              NVIC_InitStructure2.NVIC_IRQChannelPreemptionPriority = 0;
                              NVIC_InitStructure2.NVIC_IRQChannelSubPriority = 0;
                              NVIC_InitStructure2.NVIC_IRQChannelCmd = ENABLE;
                              NVIC_Init(&NVIC_InitStructure2);


                              NVIC_InitStructure3.NVIC_IRQChannel = I2C2_ER_IRQn;
                              NVIC_InitStructure3.NVIC_IRQChannelPreemptionPriority = 0;
                              NVIC_InitStructure3.NVIC_IRQChannelSubPriority = 0;
                              NVIC_InitStructure3.NVIC_IRQChannelCmd = ENABLE;
                              NVIC_Init(&NVIC_InitStructure3);
                              
                              I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE);
                              I2C_ITConfig(I2C2, I2C_IT_ERR, ENABLE);
                              I2C_ITConfig(I2C2, I2C_IT_BUF, ENABLE);
          
          
    
    i2c_init.I2C_ClockSpeed = 400000;
    i2c_init.I2C_Mode = I2C_Mode_I2C;
    i2c_init.I2C_DutyCycle = I2C_DutyCycle_2;
    i2c_init.I2C_OwnAddress1 = ST_SLAVE_ADDRESS;
    i2c_init.I2C_Ack = I2C_Ack_Enable;
    i2c_init.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Init(I2C2, &i2c_init);


    I2C_StretchClockCmd(I2C2, ENABLE);
    I2C_Cmd(I2C2, ENABLE);
          
          /* Configure the NVIC Preemption Priority Bits */
          
          NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
          
          
          NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream3_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
          
          DMA_ClearFlag(DMA1_Stream3, DMA_FLAG_TCIF3 | DMA_FLAG_TCIF3 | DMA_FLAG_TEIF3 | \
                                       DMA_FLAG_DMEIF3 | DMA_FLAG_FEIF3);
                                                                                                
          DMA_Cmd(DMA1_Stream3, DISABLE);
          while ((DMA_GetCmdStatus(DMA1_Stream3)!= DISABLE))
          {
                    printf("DMA1_Stream3 Not Yet Disabled\n");
          }     
          
          /* DMAx Channel Config */ 
          DMA_DeInit(DMA1_Stream3);
          DMA_InitStructure.DMA_Channel = DMA_Channel_7;  //DMA_Channel
          //I2C2->DR = (I2C2_BASE =(APB1PERIPH_BASE + 0x5800)) + (Address_offset for DR = 0x00000010)
          DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&I2C2->DR; //0x40005810;  
          DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)RxBuffer;
          DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
          DMA_InitStructure.DMA_BufferSize = 0x100;      
          DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
          DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
          DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
          DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
          DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
          DMA_InitStructure.DMA_Priority = DMA_Priority_High;
          DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;  
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
          DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
          DMA_Init(DMA1_Stream3, &DMA_InitStructure); 
          
          /* I2Cx DMA Enable */ 
          I2C_DMACmd(I2C2, ENABLE); 
          
          DMA_ITConfig(DMA1_Stream3, DMA_IT_DME | DMA_IT_HT | DMA_IT_TC | DMA_IT_TE, ENABLE);
          
          /* DMAy_Streamx enable */
          DMA_Cmd(DMA1_Stream3, ENABLE);
          
          while ((DMA_GetCmdStatus(DMA1_Stream3)!= ENABLE))
          {
                    printf("DMA1_Stream3 Not Yet Enabled\n");
          }                    
}


void DMA1_Stream3_IRQHandler(void)
{
     
       //STM_EVAL_LEDOn(LED4);
          if (DMA_GetITStatus(DMA1_Stream3, DMA_IT_TCIF3)) {
          STM_EVAL_LEDOn(LED3);
        // Clear DMA Stream Transfer Complete interrupt pending bit 
                    DMA_ClearITPendingBit(DMA1_Stream3, DMA_IT_TCIF3);
    }
          if (DMA_GetITStatus(DMA1_Stream3, DMA_IT_TEIF3)) {
          STM_EVAL_LEDOn(LED4);
        // Clear DMA Stream transfer error interrupt pending bit 
                    DMA_ClearITPendingBit(DMA1_Stream3, DMA_IT_TEIF3);
    }
          if (DMA_GetITStatus(DMA1_Stream3, DMA_IT_DMEIF3)) {
          STM_EVAL_LEDOn(LED5);
        // Clear DMA Stream direct mode error interrupt pending bit 
                    DMA_ClearITPendingBit(DMA1_Stream3, DMA_IT_DMEIF3);
    }
          if (DMA_GetITStatus(DMA1_Stream3, DMA_IT_HTIF3)) {
          STM_EVAL_LEDOn(LED6);
        // Clear DMA Stream half transfer complete interrupt pending bit 
                    DMA_ClearITPendingBit(DMA1_Stream3, DMA_IT_HTIF3);
    }
}


void vNordicST(void *pvParameters) 
{
     
          static int i = 0;
          printf("NordicST Task Created\n");
     
          STM_EVAL_LEDInit(LED3);
          STM_EVAL_LEDInit(LED4);
          STM_EVAL_LEDInit(LED5);
          STM_EVAL_LEDInit(LED6);
     
          taskENTER_CRITICAL();
          NordicST_I2C2_Initialization();
          taskEXIT_CRITICAL();
          taskYIELD();
          while(1) {
                    taskENTER_CRITICAL();
               
                    //SleepMode_Measure();               
          
                    __WFI();
                    USART_Initialization();
                    printf("*****USART Second Initialization Done*****\n");
               
                    while (!I2C_CheckEvent(I2C2, I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED))
                    {
                    }
                    
                    while (!I2C_CheckEvent(I2C2, I2C_EVENT_SLAVE_STOP_DETECTED))
                    {
                    }


                    while(count < 256) {
                              printf("Count : %d", count++);
                              printf(" RxBufferss 0x%x\n", RxBuffer[i++]);
                    }
                    count = 0;
                    i = 0;
                    taskEXIT_CRITICAL();
          }
          vTaskDelete( NULL );
}

Outcomes