cancel
Showing results for 
Search instead for 
Did you mean: 

Having trouble with USART6 RECEIVE

anonymous.8
Senior II
Posted on October 19, 2017 at 20:57

Hi, I am having trouble getting my USART6 receive on PORT PC7 working.

I have USART6 initialized at 115200 baud in TX and RX mode and can transmit fine on USART6 PORT PC6. In order to test USART6 reception I have a simple forever polled loop which echoes the USART6 received bytes onto my debug port which is UART7. UARt7 Transmit works fine. but I do not see any data coming in on USART6 which is coming from a GPS receiver, verified by monitoring the incoming data in another serial terminal window.

My echoing loop is as follows:

while (true)

{

      // Do we have a received character in USART6?

      if ((USART6->ISR & USART_ISR_RXNE) == USART_ISR_RXNE)

      {

         // Then transmit it on the Debug port, UART7.

         uint8_t receivedByte = (uint8_t)(USART6->RDR & 0xFF); // This also clears the USART_ISR_RXNE bit.

         // Loop until transmit data register is empty

         while (!(UART7->ISR & USART_FLAG_TXE));

         UART7->TDR = (uint32_t)receivedByte;

      }

}

My initialization code is here:

void

InitGPSUARTTx

(

uint32_t

baudRate

)

{

// Enable USART6 clock

RCC

->APB2ENR |=

RCC_APB2ENR_USART6EN

;

// Configure PC6 USART6 TX as alternate function I/O for USART6

GPIOSetAltFunc

(

GPSUART6GPIO

,

GPSUART6TxOutPin

|

GPSUART6RxInPin

, GPIO_PuPd_NOPULL, GPIO_OType_PP,

GPIO_AF8_USART6

);

USART_SetConfig

(

USART6

,

USART_MODE_TX_RX

,

baudRate

);

// UART6 default clock is from PCLK1 which is initially set to 54MHz

// because of the initial half speed 108MHz AHB/PHB busses.

// Those bus speeds are later increased to 216MHz in InitSDCard()

// after the SD card initialization at the lower bus speed.

// Set GPS USART6 BRR register for 108MHz / 115200.

// this gives a better match to 115200 than the computed value from USART_SetConfig()

// This value has been determined experimentally by measuring the actual transmission rate.

USART6

->BRR = 938;

// Enable USART6

USART6

->CR1 |=

USART_CR1_UE

;

}

The

GPIOSetAltFunc()

and

USART_SetConfig() are my own functions that have been widely proven elsewhere in my application to simply set the AF modes for GPIO pins and also a simplified USART Config, that originally derived from the STD periph lib.

Am I missing something obvious here? Any help is appreciated, thanks.
5 REPLIES 5
Posted on October 19, 2017 at 21:33

Asssuming an STM32F7xx part.

What is the out-going rate on UART7?

Any other status showing on USART6->ISR ?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 19, 2017 at 21:38

Clive, yes it's an STM32F746NG part (STM32F7 DISCO board).

Outgoing baud rate on UART7 debug port is 460800, very fast, so it shouldn't block the next receiver byte coming in on USART6. Haven't looked at other USART6->ISR statuses yet. Will do soon.

USART6->ISR = 0x006000F8 before  the RDR register is read and USART6->ISR = 0x006000D8 afterwards.

S.Ma
Principal
Posted on October 20, 2017 at 07:36

I smell IP changes for USART vs UART hence the code might have to be tuned, such as (in the ref man 31.2 USART main features):

Convenient baud rate programming independent from the PCLK reprogramming

Received/transmitted bytes are buffered in reserved SRAM using centralized DMA

Separate enable bits for transmitter and receiver

Swappable TX/RX

I guess you'd need to read the ref man and dig some more. Maybe showing the IP version in the Ref Man let user tell if porting a SW from one family to another requires edits.

anonymous.8
Senior II
Posted on October 20, 2017 at 23:11

Here's what else I have discovered. If I transmit on the USART6 TX line BEFORE I try to receive, the receive is blocked, I can receive only one character then it stops altogether. But if I do not transmit anything, the USART6 RX works OK.

This almost seems like it is going into a half-duplex mode automatically, but the half-duplex mode bit HDSEL in CR3 register is never set, it is 0. I have checked the Silicon Errata document and there is nothing there that explains this strange behavior.
Posted on October 20, 2017 at 21:23

Well, yes I've read the reference manual over and over and have reduced my USART6 init code to just a few bare lines, can't get any simpler than this, but still it won't echo the USART RX line:

It is hardcoded to 115200 baud rate (verified by logic analyzer), 8 data bits 1 stop bit, no parity.

void

InitGPSUARTTx

(

void

)

{

// Enable USART6 clock

RCC

->APB2ENR |=

RCC_APB2ENR_USART6EN

;

// Configure PC6 USART6 TX as alternate function I/O for USART6

GPIOSetAltFunc

(

GPSUART6GPIO

,

GPSUART6TxOutPin

|

GPSUART6RxInPin

, GPIO_PuPd_NOPULL, GPIO_OType_PP,

GPIO_AF8_USART6

);

// Now set up CR1 config for 8 data bits, NO parity, 16 bit oversampling, everything else disabled.

// Now set up CR2 config for USART_POLARITY_LOW | USART_PHASE_1EDGE | USART_STOPBITS_1

USART6

->CR1 =

USART_CR1_TE

|

USART_CR1_RE

;  // Enable TX and RX.

USART6

->CR2 = 0;

USART6

->CR3 = 0;

// Set GPS USART6 BRR register for 108MHz / 115200.

// This value has been determined experimentally by measuring the actual transmission rate.

USART6

->BRR = 938;

// Enable USART6

USART6

->CR1 |=

USART_CR1_UE

;

}

void

EchoGPSData

(

void

)

{

  

while

(

true

)

     {

      // Do we have a received character in USART6?

      

if

((

USART6

->ISR &

USART_ISR_RXNE

) ==

USART_ISR_RXNE

)

          {

        // Then transmit it on the Debug port, UART7.

       

uint8_t

receivedByte = (

uint8_t

)(

USART6

->RDR & 0xFF);

// This also clears the USART_ISR_RXNE bit.

        // Loop until transmit data register is empty

        

while

(!(

UART7

->ISR &

USART_FLAG_TXE

));

        

UART7

->TDR = (

uint32_t

)receivedByte;

      }

   }

}