AnsweredAssumed Answered

USARTx->DR not getting updated.

Question asked by vora.anuja on Apr 25, 2014
Latest reply on Apr 6, 2015 by Inventor(y)
Hi,
I'm trying to implement interrupt based UART on STM32f4- Discovery board.
I get the Tx interrupt but when I call the void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) , the USARTx-> DR register does not reflect the value it is assigned.
I cannot see any Data on the oscilloscope either.

My code is pasted below and I have attached the Screenshot of the Disassembly and Local variables window.

Any help will be appreciated. 
bool CUartStm::Configure()
{
    // Check baud rate.
    if (muiBaudRate_baud == 0) return false;

    // Enable the UART interrupt
    IrqEnable();
    
    // Disable the UART Receive interrupt.
    USART_ITConfig(moUart_t, USART_IT_RXNE, DISABLE);
       
    // Disable the UART Transmit interrupt.
    USART_ITConfig(moUart_t, USART_IT_TXE, DISABLE);    
    
    // Configure RCC clock.
    RccConfiguration();
    
    // Configure RCC clock.
    GpioConfiguration();   
   
    // Populate UART structure.
    USART_InitTypeDef oUartStruct = 
    {
        muiBaudRate_baud,                    // Baud rate.
        USART_WordLength_8b,                 // Word length: 8 bits
        USART_StopBits_1,                    // Stop bits: 1
        USART_Parity_No,                     // No parity.
        (USART_Mode_Rx | USART_Mode_Tx),     // Mode set to Rx and Tx.
        USART_HardwareFlowControl_None       // No Hardware Flow Control.
    };
    
    // Initialize UART registers.
    USART_Init(moUart_t, &oUartStruct);

    // Enable the USART
    USART_Cmd(moUart_t, ENABLE);

    // Enable the Receive interrupt.
    USART_ITConfig(moUart_t, USART_IT_RXNE, ENABLE);
       
    // Enable the Transmit interrupt. 
    USART_ITConfig(moUart_t, USART_IT_TXE, ENABLE);
    
    return true;
}

/**
 *  @brief  Configure the GPIO pins for the Uart.
 *
 *  @detail
 *  @param                     None.
 *  @return                    None.
 */
 void CUartStm::GpioConfiguration()
{
   // Populate GPIO structure.
   GPIO_InitTypeDef oGpioStruct = 
   {
        GPIO_Pin_All,           // GPIO pins to be configured..
        GPIO_Mode_AF,           // Mode: Alternate Function.
        GPIO_Speed_50MHz,       // Speed of selected pins : 50MHz
        GPIO_OType_PP,          // GPIO Output Type.
        GPIO_PuPd_UP            // Pull Up.
   };
  
  switch(mePeripheralId)
  {
    case eUart1:
      // Configure the Pin 9 of Port A as Alternate function.
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
      
      // Configure the Pin 10 of Port A as Alternate function.
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
      
      // Configure Pins 9 and 10 for UART1
      oGpioStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
      
      // Initialse GPIO 
      GPIO_Init(GPIOA, &oGpioStruct);
      
    break;
      
    case eUart2:
      // Configure the Pin 2 of Port A as Alternate function.
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
      
      // Configure the Pin 3 of Port A as Alternate function.
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
      
      // Configure Pins 2 and 3 for UART2
      oGpioStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
      
      // Initialse GPIO 
      GPIO_Init(GPIOA, &oGpioStruct);
      
    break;   
    
    case eUart3:
      // Configure the Pin 10 of Port B as Alternate function.
      GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
      
      // Configure the Pin 11 of Port B as Alternate function.
      GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
      
      // Configure Pins 10 and 11 for UART3
      oGpioStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
      
      // Initialse GPIO 
      GPIO_Init(GPIOB, &oGpioStruct);
      
    break;  
    
    case eUart4:
      // Configure the Pin 10 of Port C as Alternate function.
      GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4);
      
      // Configure the Pin 11 of Port C as Alternate function.
      GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4);
      
      // Configure Pins 10 and 11 for UART4
      oGpioStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
      
      // Initialse GPIO 
      GPIO_Init(GPIOC, &oGpioStruct);
      
    break;  
    
    case eUart5:
      // Configure the Pin 12 of Port C as Alternate function.
      GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
      
      // Configure the Pin 2 of Port D as Alternate function.
      GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
      
      // Configure Pin 12 for UART5 Tx
      oGpioStruct.GPIO_Pin = GPIO_Pin_12 ;
      
      // Initialse GPIO 
      GPIO_Init(GPIOC, &oGpioStruct);
      
      // Configure Pin 2 for UART5 Rx
      oGpioStruct.GPIO_Pin = GPIO_Pin_2 ;
      
      // Initialse GPIO 
      GPIO_Init(GPIOD, &oGpioStruct);
      
    break;  

    case eUart6:
      // Configure the Pin 6 of Port C as Alternate function.
      GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);
      
      // Configure the Pin 7 of Port C as Alternate function.
      GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);
      
      // Configure Pins 6 and 7 for UART3
      oGpioStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
      
      // Initialse GPIO 
      GPIO_Init(GPIOC, &oGpioStruct); 
      
    break;
    
    default:
      // Error Message
    break;
    }
}

/**
 *  @brief  Configure the RCC clock for the Uart.
 *
 *  @detail
 *  @param                     None.
 *  @return                    None.
 */
 void CUartStm :: RccConfiguration()
{
  switch(mePeripheralId)
  {
    case eUart1:
      // Enable GPIO Clock.
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
      
      // Enable Peripheral Clock.
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
      
    break;
    
    case eUart2:
      // Enable GPIO Clock.
      RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
      
      // Enable Peripheral Clock.
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
      
    break; 
    
    case eUart3:
      // Enable GPIO Clock.
      RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
      
      // Enable Peripheral Clock.
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
      
    break;  

    case eUart4:
      // Enable GPIO Clock.
      RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
      
      // Enable Peripheral Clock.
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);
      
    break;

    case eUart5:
      // Enable GPIO Clock.
      RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
      RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);      
      
      // Enable Peripheral Clock.
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);
      
    break;

    case eUart6:
      // Enable GPIO Clock.
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
      
      // Enable Peripheral Clock.
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE);
      
    break;    
      
    default:
      // Error Message
    break;
  }
}

/**
 *  @brief  Enable the Interrupt for the Uart.
 *
 *  @detail
 *  @param                     None.
 *  @return                    None.
 */
void CUartStm :: IrqEnable()
  {
    NVIC_InitTypeDef oNVICStruct =
    {
      USART1_IRQn,        // IRQ Channel to be Enabled or Disabled.
      2,                  // Pre-emption priority for the IRQ channel.
      2,                  // Subpriority level for the IRQ channel.
      ENABLE              // IRQ channel defined in NVIC_IRQChannel will be Enabled.
    };
    
    switch(mePeripheralId)
    {
      case eUart1:
        oNVICStruct.NVIC_IRQChannel = USART1_IRQn;
        NVIC_Init(&oNVICStruct);
      break;
      
      case eUart2:
        oNVICStruct.NVIC_IRQChannel = USART2_IRQn;
        NVIC_Init(&oNVICStruct);
      break; 
      
      case eUart3:
        oNVICStruct.NVIC_IRQChannel = USART3_IRQn;
        NVIC_Init(&oNVICStruct);
      break;
      
      case eUart4:
        oNVICStruct.NVIC_IRQChannel = UART4_IRQn;
        NVIC_Init(&oNVICStruct);
      break;

      case eUart5:
        oNVICStruct.NVIC_IRQChannel = UART5_IRQn;
        NVIC_Init(&oNVICStruct);
      break;

      case eUart6:
        oNVICStruct.NVIC_IRQChannel = USART6_IRQn;
        NVIC_Init(&oNVICStruct);
      break;

      default:
        // Error Message
      break;      
    }
  }

int main(void)
{
        if (SysTick_Config(SystemCoreClock / 1000))
    { 
        /* Capture error */ 
        while (1);
    }
    
    
        //UART Modifications
    bool bSuccess = false;
    unsigned char ucData = 0;
    unsigned char ucUartPeriph = 2;
    unsigned long int uibaudrate = 9600;
    unsigned long int uisystemclock = 0;
    
    CUartQueue *mpoTxQueue = nullptr;
    CUartQueue *mpoRxQueue = nullptr;
    
    
    // Create UART pointer object
    CUart *mpoUart;           
    
    // Create a new object for ST micro.
    mpoUart = new CUartStm(ucUartPeriph, uibaudrate, uisystemclock, mpoTxQueue, mpoRxQueue);
    
    // Initialize UART
    bSuccess = mpoUart->Configure();
}

UART ISR
extern "C"  void USART3_IRQHandler(void) 
    {
      static int tx_index = 0;
      static int rx_index = 0;
     
      unsigned char ucTxStringLoop[] = "Hello." ;
      unsigned char ucRxStringLoop[10] ;
   
      if (USART_GetITStatus(USART3, USART_IT_TXE) != RESET) // Transmit the string in a loop
      {
        USART_SendData(USART3, ucTxStringLoop[tx_index++]);
   
        if (tx_index >= (sizeof(ucTxStringLoop) - 1))
        tx_index = 0;
      }
   
      if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) // Received characters modify string
      {
        ucRxStringLoop[rx_index++] = USART_ReceiveData(USART3);
   
        if (rx_index >= (sizeof(ucRxStringLoop) - 1))
        rx_index = 0;
      }
   }




Outcomes