3

I'm working with STM32F427 UASRT1 via the following class:

void DebugUartOperator::Init() {
    // for USART1 and USART6 
    ::RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    // USART1 via PORTA 
    ::RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 

    ::GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
    ::GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

    GPIO_InitTypeDef GPIO_InitStruct;

    // fills the struct with the default vals: 
    // all pins, mode IN, 2MHz, PP, NOPULL
    ::GPIO_StructInit(&GPIO_InitStruct); 

    // mission-specific settings:
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    ::GPIO_Init (GPIOA, &GPIO_InitStruct);

    USART_InitTypeDef USART_InitStruct;

    // 9600/8/1/no parity/no HWCtrl/rx+tx
    ::USART_StructInit(&USART_InitStruct); 

    USART_InitStruct.USART_BaudRate = 921600;
    USART_InitStruct.USART_WordLength = USART_WordLength_9b;
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
    USART_InitStruct.USART_Parity = USART_Parity_Odd;
    ::USART_Init(USART1, &USART_InitStruct);

    ::USART_Cmd(USART1, ENABLE);
    }

void DebugUartOperator::SendChar(char a) {
    // wait for TX register to become empty
    while(::USART_GetFlagStatus(USART1, USART_FLAG_TXE) != SET);
    ::USART_SendData(USART1, static_cast<uint8_t>(a));
    }

The problem is that every now and then USART starts ignoring actual 8th data bit and setting it as a parity bit (odd parity, to be specific). The strangest of all that it sometimes happens even after a long poweroff, without any prior reprogramming or something. For example yesterday evening it was all OK, then next morning I come to work, switch the device on and it starts working the way described. But it's not limited to this, it may randomly appear after some next restart.

That effect is clearly visible with the oscilloscope and with different UART-USB converters used with diffrent programs. It is even possible, once this effect have appeared, to reprogram a microcontroller to transmit test data sets. For example, 0x00 to 0xFF in endless cycle. It does not affect the problem. Changing speeds (down to 9600 bps), bits per word, parity control does not help - the effect remains intact even after repropramming (resulting for example in really abnormal 2 parity bits per byte). Or, at least, while UASRT is being initialized and used in the usual order according to my program's workflow.

The only way to fix it is to make the main() function do the following:

int main() {
    DebugUartOperator dua;
    dua.Init();
    while(1) {
        uint8_t i;
        while(++i)
            dua.SendChar(i);
        dua.SendChar(i);
        }
    }

With this, after reprogramming and restart, the first few bytes (up to 5) are transmitted rotten but then everything works pretty well and continues to work well through further restarts and reprograms.

This effect is observed on 2 different STM32F427s on 2 physically different boards of the same layout. No regularity is noticed in its appearance. Signal polarity and levels conform USART requirements, no noise or bad contacts are dectected during investigation. There seems to be no affection to UASRT1 from the direction of other code used in my program (either mine or library one) or it is buried deeply. CMSIS-OS is used as RTOS in the project, with Keil uVision 5.0.5's RTX OS.

Need help.

Victor Che
  • 75
  • 7
  • Hi Vasily, sorry I can't see your real question here. You say that _USART starts ignoring actual 8th data bit and setting it as a parity bit (odd parity, to be specific)._ But you have setup `USART_InitStruct.USART_Parity = USART_Parity_Odd;` Is that the problem? – EricPb Nov 03 '15 at 01:42
  • Unfortunately not. I mentioned later that "changing... parity control does not help": I've tried both odd and even modes, as well as no parity mode, 8- or 9-bit width words - no, the effect stays once it's come. – Victor Che Nov 03 '15 at 06:32
  • Interesting though that after getting rid of my other problem with resource leakage in CMSIS-RTOS (http://stackoverflow.com/questions/32995099/cmsis-rtoss-osmailfree-returns-some-address-instead-of-osstatus-type-value) the problem being discussed has also vanished. Or, at least, this effect isn't showing up anymore for some considerable amount of time. – Victor Che Nov 03 '15 at 06:40

1 Answers1

1

In STM's you can specify wordlength for usart / uart transmission but wordlength is a sum of data bits and bit parity. So if you would like to have 8 bit data and even parity bit, you have to specify UART_WORDLENGTH_9B andUART_PARITY_EVEN.

You can also have 9 bits of data, with no parity. In reference manual for F427 section 30.6.4, Bit 12 we see that it should be possible to set 9 data bits, but term data bits is also applicable to parity bit.

Bit 12M: Word length
This bit determines the word length. It is set or cleared by software.
0: 1 Start bit, 8 Data bits, n Stop bit
1: 1 Start bit, 9 Data bits, n Stop bit

Final answer is in 30.6.4, Bit 10

This bit selects the hardware parity control (generation and detection). When the parity control is enabled, the computed parity is inserted at the MSB position (9th bit if M=1; 8th bit if M=0) and parity is checked on the received data. This bit is set and cleared by software. Once it is set, PCE is active after the current byte (in reception and in transmission).

s.paszko
  • 633
  • 1
  • 7
  • 21