2017-10-19 11:57 AM
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()
andUSART_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.2017-10-19 12:33 PM
Asssuming an STM32F7xx part.
What is the out-going rate on UART7?
Any other status showing on USART6->ISR ?
2017-10-19 02:38 PM
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.
2017-10-19 10:36 PM
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.
2017-10-20 02:11 PM
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.2017-10-20 02:23 PM
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;
}
}
}