2023-05-08 11:21 PM
Hey folks, I did try the bare metal programming videos on Udemy, and got so facinated, that decided to try on other board. As expected the code from the tutorial is not working on the other board. However I have checked, and re cheked the registry values that I provide, with the documentation of the correct board, and all seems to be OK, In addition to that I added 120 MHz for APB1 bus frequency, but I am still not getting anything on RealTerm.
In Udemy they do not respond to my questions, regarding other boards, so I really hope to get some help here. Thank you!
The device is Nucleo L4R5ZI, here is the code:
#include <stdint.h>
#include <stdio.h>
#include "stm32l4xx.h"
#define GPIOAEN (1U<<0)
#define UART2EN (1U<<17)
#define SYS_FREQ 120000000
#define APB1_CLK SYS_FREQ
#define CR1_TE (1U<<3)
#define CR1_UE (1U<<0)
#define ISR_TXE (1U<<7)
static uint16_t compute_uart_div(uint32_t PeriphClk, uint32_t Baudrate);
static void uart_set_baudrate (USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t Baudrate);
static void uart2_write(uint8_t ch);
void uart2_tx_init (USART_TypeDef *USARTx);
int __io_putchar (int ch)
{
uart2_write(ch);
return ch;
}
int main(){
uart2_tx_init (USART2);
while (1)
{
printf ("Hello from STM32L4....\n\r");
}
}
void uart2_tx_init (USART_TypeDef *USARTx)
{
//*******************Configure the UART pin*******************
//Enable clock access to GPIOA for PA2 as TX line
RCC->AHB2ENR |= GPIOAEN;
//Set PA2 mode as alternate function mode
GPIOA->MODER &=~(1U<<4);
GPIOA->MODER |=(1U<<5);
//Set the alternate function type to UART
GPIOA->AFR[0] |=(1U<<8);
GPIOA->AFR[0] |=(1U<<9);
GPIOA->AFR[0] |=(1U<<10);
GPIOA->AFR[0] &=~(1U<<11);
//*******************Configure the UART module*******************
//Enable clock access to UART2
RCC->APB1ENR1 |=UART2EN;
//Configure baudrate
uart_set_baudrate (USARTx, APB1_CLK, 115200);
//Configure transfer direction
USARTx->CR1 = CR1_TE;
// Enable UART module
USARTx->CR1 |= CR1_UE;
}
static void uart2_write(uint8_t ch)
{
//Wait for transmit data register to be empty
while (!(USART2->ISR & ISR_TXE)) {}
//Transmit value
USART2->TDR = (ch & 0xFF);
}
static void uart_set_baudrate (USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t Baudrate)
{
USARTx->BRR = compute_uart_div( PeriphClk, Baudrate);
}
static uint16_t compute_uart_div(uint32_t PeriphClk, uint32_t Baudrate)
{
return ((PeriphClk + (Baudrate/2))/Baudrate);
}
Solved! Go to Solution.
2023-05-09 04:23 AM
@Valkan Pavlov how results?
2023-05-09 10:28 AM
It was definatley part of the issue, but I have not manage to make it work yet. I have posted the new code in the answer to Peter.
2023-05-09 10:35 AM
Hi Peter,
Thanks for the welcome, and the answer!
It was really the case, that LPUART1 is connected to the virtual COM port. I did try to set it up, and ended up with this:
#include <stdint.h>
#include <stdio.h>
#include "stm32l4xx.h"
#define GPIOGEN (1U<<6)
#define LPUART1EN (1U<<0)
#define SYS_FREQ 4000000 //It is 4MHz!
#define APB1_CLK SYS_FREQ
#define CR1_TE (1U<<3)
#define CR1_UE (1U<<0)
#define ISR_TXE (1U<<7)
static uint16_t compute_LPUART_div(uint32_t PeriphClk, uint32_t Baudrate);
static void LPUART_set_baudrate (USART_TypeDef *LPUARTx, uint32_t PeriphClk, uint32_t Baudrate);
static void LPUART1_write(USART_TypeDef *LPUARTx, uint8_t ch);
void uart2_tx_init (USART_TypeDef *LPUARTx);
int __io_putchar (int ch)
{
LPUART1_write(LPUART1, ch);
return ch;
}
int main(){
LPUART1_tx_init (LPUART1);
while (1)
{
printf ("Hello from STM32L4....\n\r");
}
}
void LPUART1_tx_init (USART_TypeDef *LPUARTx)
{
//*******************Configure the UART pin*******************
//Enable clock access to GPIOG for PG7 as TX line
RCC->AHB2ENR |= GPIOGEN;
//Set PG7 mode as alternate function mode
GPIOG->MODER &=~(1U<<14);
GPIOG->MODER |=(1U<<15);
//Set the alternate function type to TX - AF8
GPIOG->AFR[0] &=~(1U<<28);
GPIOG->AFR[0] &=~(1U<<29);
GPIOG->AFR[0] &=~(1U<<30);
GPIOG->AFR[0] |=(1U<<31);
//*******************Configure the UART module*******************
//Enable clock access to LPUART1
RCC->APB1ENR2 |= LPUART1EN;
//Configure baudrate ?????
LPUART_set_baudrate (LPUART1, APB1_CLK, 115200); //?????
//Configure transfer direction
LPUART1->CR1 = CR1_TE;
// Enable UART module
LPUART1->CR1 |= CR1_UE;
}
static void LPUART1_write(USART_TypeDef *LPUARTx, uint8_t ch)
{
//Wait for transmit data register to be empty
while (!(LPUARTx->ISR & ISR_TXE)) {}
//Transmit value
LPUARTx->TDR = (ch & 0xFF);
}
static void LPUART_set_baudrate (USART_TypeDef *LPUARTx, uint32_t PeriphClk, uint32_t Baudrate)
{
LPUARTx->BRR = compute_LPUART_div( PeriphClk, Baudrate);
}
static uint16_t compute_LPUART_div(uint32_t PeriphClk, uint32_t Baudrate)
{
return ((PeriphClk + (Baudrate/2))/Baudrate);
}
It is not working, my baudrate formula is probably wrong, together with the SYS_FREQ that should be 32.768 MHz? If you have any more valuable advices, including learning resourses it will be greatly appreciated!
Thanks!
2023-05-11 02:19 AM
You still init USART2, line 37
2023-05-11 03:13 AM
It is amazing how can I omit obvious things. Thank you. I will try again.
2023-05-11 03:24 AM
nice 🙂 please some answer as the best as we can close topic 🙂 OF course after the test :D
2023-05-11 03:25 AM
It's magic of review code :D
2023-05-11 04:06 AM
Hi, I was able to validate the default system clock speed of 4 MHz, and maybe fix the errors. But still miss something. Maybe the LPUART require more things to work.... back to tutorials, maid be early to start projects on my own. Thank you for the assistance!
2023-05-13 02:54 AM
> However I have checked, and re cheked the registry values that I provide
Again someone who defines their own register bit field definitions and uses magic numbers. Use the provided standard CMSIS definitions!