2015-10-08 06:10 AM
I'm trying to set up communication between the USART2 on stm32f411xe nucleo and a PC using the STLink Virtual COM Port (COM3). I'm avoiding the ST HAL or Standard Peripheral Library as a beginner as far as possible.
The relevant code is as under:
main.c: ... ...usart2Init();
usart2PutChar('C'); while(1) { userLedToggle(); delayMs(500); } ... ... void usart2Init(void) { uint32_t temp = 0x0; static uint8_t usart2Initialized = 0x0; if(!usart2Initialized) { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; temp = GPIOA->MODER; temp &= ~(GPIO_MODER_MODER2 | GPIO_MODER_MODER3); temp |= ((GPIO_MODE_AF << 4) | (GPIO_MODE_AF << 6)); GPIOA->MODER = temp; GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_2 | GPIO_OTYPER_OT_3); GPIOA->OTYPER |= ((GPIO_OTYPE_PP << 4) | (GPIO_OTYPE_PP << 6)); temp = GPIOA->OSPEEDR; temp &= ~(GPIO_OSPEEDER_OSPEEDR2 | GPIO_OSPEEDER_OSPEEDR3); temp |= ((GPIO_SPEED_HIGH << 4) | (GPIO_SPEED_HIGH << 6)); GPIOA->OSPEEDR = temp; temp = GPIOA->PUPDR; temp &= ~(GPIO_PUPDR_PUPDR2 | GPIO_PUPDR_PUPDR3); temp |= ((GPIO_PUPD_NONE << 4) | (GPIO_PUPD_NONE << 6)); GPIOA->PUPDR = temp; temp = GPIOA->AFR[0]; temp &= ~(GPIO_AFRL_AFRL_2 | GPIO_AFRL_AFRL_3); temp |= ((GPIO_AF7_USART2 << 8) | (GPIO_AF7_USART2 << 12)); GPIOA->AFR[0] = temp; RCC->APB1ENR |= RCC_APB1ENR_USART2EN; USARTConfig_Typedef USARTConfig; USARTConfig.baudRate = 9600; USARTConfig.mode = (USART_CONFIG_MODE_TX); USARTConfig.parity = USART_CONFIG_PARITY_NONE; USARTConfig.wordLength = USART_CONFIG_WL8; USARTConfig.stopBits = USART_CONFIG_SB_20; USARTConfig.overSampling = USART_CONFIG_OS16; usart2Config(&USARTConfig); usart2Initialized = 0x1; } } void usart2Config(USARTConfig_Typedef * c) { uint32_t temp = 0x0; USART2->CR1 |= USART_CR1_UE; temp = USART2->CR1; temp &= ~(USART_CR1_OVER8 | USART_CR1_M | USART_CR1_PS | USART_CR1_PCE); temp |= (c->mode | c->wordLength | c->parity | c->overSampling); USART2->CR1 = temp; temp = USART2->CR2; temp &= ~USART_CR2_STOP; temp |= c->stopBits; USART2->CR2 = temp; USART2->BRR = USART_BRR(getAPB1ClkFreq(), c->baudRate); USART2->CR1 |= c->mode; } void usart2PutChar(uint8_t d) { while(!(USART2->SR & USART_SR_TXE)) ; USART2->DR = (d & (uint8_t)0xFF); }With this code, the data on Realterm and PuTTY on the PC is garbled. The configuration is the same on both ends:
Baud Rate: 9600 Databits (Word Length): 8 Stopbits: 2 I've tried various baud rates/stop bits and verified the configuration each time by reading the USART2_BRR, USART2_CR1/2/3 registers but to no good. If it helps, the data that appears as 'Binary' on Realterm is 11111110 00011110 11111110. Any pointers would be very helpful. Thanks. #stm32 #stm32f4 #usart2015-10-08 06:59 AM
So by avoiding all this stuff as a beginner, does it make it easier, or more likely to get support from others?
So stick a scope of the pins and confirm the bit rate is right. Most probably an issue related to the assumed clock rate, external clock as HSE_VALUE, or the PLL configuration. The math computing values is predicated on knowing the source clocks correctly. Failure to use the BYPASS setting for the HSE can result in the clock being wrong when the signal comes from an external source (not crystal) What does the APB clock report as being? You can also output internal clocks via PA8 (MCO) and measure those.2015-10-09 06:46 AM
clive1,
Yes, it does make me uncomfortable to ask people to go through MY smoke and mirrors and I'm grateful for your help but I'm left with no choice! The ST HAL seems too involved and... layered! The peripheral library on the other hand is deprecated and seems not available for STM32F411... Don't have a scope yet unfortunately, so I tried using different sources for the clocks; the internal HSI, PLL with HSI as the source as well as external clock (using the crystal on ST Link by setting the HSE Bypass bit) but to no avail. However! It works if the over-sampling is by 8 (OVER8 bit set) and doesn't work when the over-sampling is by 16. This is the case with all the clock sources. This is surprising since the reference manual states that setting the over sampling to 16 makes it more tolerant to variations in the clock. How do you reckon oversampling as the reason behind this?2015-10-09 08:36 AM
I've built F411 stuff with the SPL, it's deprecated in heads of some at ST, but it's functional code that's solid, and not suffering bit rot. I'm a lot more skeptical about embedded code that has to be updated every few weeks to address the most current set of bugs and quirks.
The 411 is supported in the F4 DSP Library 1.5.1 (basically SPL + CMSIS DSP code) STM32F4xx_DSP_StdPeriph_Lib_V1.5.1\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm\startup_stm32f411xe.s I'd have to mine into the registers, and what exactly is happening here, but I'm not keen on doing that. I prefer to post one example that works than use the Edison approach of fixing 1000 individual failing examples, believe me it's get's to be tiresome. I've got an F411 DISCO, don't think I have a NUCLEO to hand, but pretty sure I could put together a USART example with the right system_stm32f4xx.c and startup_stm32f4xx.s files.2015-10-10 06:10 AM
Ah alright... I have the STMf4xx SPL now. I think I'll use that henceforth. Thanks.