cancel
Showing results for 
Search instead for 
Did you mean: 

LPUART no output

JS8
Senior

Hello,

I am programming an STM32WB55CGU6 on custom PCB. I'm using the LPUART1 peripheral according to the datasheet and reference manual, but at the transmitter pin (PA2) I'm not seeing any traffic. It's just stable at about 3.3V. There is a led at PC15 and it is blinking, so the program is not getting stuck anywhere. What is wrong with the LPUART? Can't find any answers in the documentation.. I'd appreciate if you could check out my code and point out any problems.

Thanks

 

#include <stdlib.h>

#define CLOCK_ENABLE_GPIOBC 6
#define PIN_SET_PC15 1<<15
#define PIN_SET_PB8 1<<8
#define MODE_SELECT_PC15 1<<30
#define MODE_SELECT_PB8 1<<16
#define uint32_t unsigned int
static uint32_t RCC = (uint32_t)0x58000000;
static uint32_t LPUART1 = (uint32_t)0x40008000;
static uint32_t LPUART1_TDR = (uint32_t)0x40008028;
static uint32_t FLASH = (uint32_t)0x08000000;
static uint32_t TIM2 = (uint32_t)0x40000000;
static uint32_t TIM2_CNT = (uint32_t)0x40000024; 
static uint32_t GPIOA = (uint32_t)0x48000000;
static uint32_t GPIOB = (uint32_t)0x48000400;
static uint32_t GPIOC = (uint32_t)0x48000800;
static uint32_t GPIOD = (uint32_t)0x48000C00;
static uint32_t GPIOE = (uint32_t)0x48001000;

static void write(uint32_t address, uint32_t value, int set)
{
	if(set) {
		*(uint32_t volatile*)(address) = value;
	} else {
		*(uint32_t volatile*)(address) |= value;
	}
}

static uint32_t read(uint32_t address)
{
	return *(uint32_t volatile*)(address);
}

static void write_UART(char* data, int len)
{
	int i;
	for(i = 0; i < len; i += 1)
	{
		while(!(read(LPUART1 + 0x1C) & (1<<7))) {}
			
		write(LPUART1_TDR, (uint32_t)data[i], 1);
	}
	
	while(!(read(LPUART1 + 0x1C) & (1<<6))) {}
}

static void write_pin(uint32_t GPIO, uint32_t PIN, uint32_t state)
{
	if(state)
	{
		write(GPIO + 0x14, 1<<PIN, 0);
	} else {
		write(GPIO + 0x14, read(GPIO + 0x14) & ~(1<<PIN), 1);
	}
	
}

static void setup(void)
{
	write(RCC, (1<<16 | 1<<19), 0); /* HSEON, HSE CSS ON */ 
	
	__asm("DSB");
	
	while(!(read(RCC) & (1<<17)))
	{}
	
	write(RCC + 0x8, 0x2, 0); /* SET HSE AS SYSCLK */
		
	write(FLASH, 1, 0);
		
	__asm("DSB");
		
	while(!(read(RCC + 0x008) & (1<<17)))
	{}
		
	write(RCC + 0x04C, CLOCK_ENABLE_GPIOBC, 0);
	
	write(GPIOC, MODE_SELECT_PC15, 1);
	write(GPIOB, MODE_SELECT_PB8, 1);
	write(GPIOA, (1<<7) + (1<<5), 1); /* SET PA2, PA3 MODES AS ALTERNATE FUNCTION */
		
	write(RCC + 0x058, 0x1, 0); /* ENABLE CLOCK TO TIM2 */
	write(RCC + 0x05C, 0x1, 0); /* ENABLE CLOCK TO LPUART1 */
		
	write(GPIOA + 0x20, (1<<15) + (1<<11), 1); /* SET PA2 AND PA3 ALTERNATE FUNCTIONS AS AF8 (LPUART1_TX, LP_UART1_RX) */
	
	write(TIM2 + 0x28, 32000 - 1, 1); /* SET TIM2 PRESCALER */
	write(TIM2 + 0x2C, 1010 -1, 1); /* SET TIM2 ARR */
	write(LPUART1 + 0x0C, 115200, 1); /* SET LPUART1 BAUD RATE */
	
	__asm("DSB");
	
	write(TIM2, 1, 0); /* CNT ENABLE */
	write(LPUART1, 0x1, 0); /* LPUART1 ENABLE */
	write(LPUART1, 1<<3, 0); /* transmitter enable */
}

int main(void)
{
	uint32_t state = 1;
	char data[] = "hello world\n";
	setup();
	
	write_pin(GPIOC, 15, 1);
	
	write_UART(data, 11);
	
	
	while(1)
	{
		__asm("DSB");
		if(read(TIM2_CNT) >= 1000)
		{
			if(state)
			{
				write_pin(GPIOC, 15, 0);
				write_UART(data, 12);
				state = 0;
			} 
			else if(state == 0)
			{
				write_pin(GPIOC, 15, 1);
				write_UART(data, 11);
				state = 1;
			}
			
		}
	}
	
}

 

1 ACCEPTED SOLUTION

Accepted Solutions

There's about ONE person coding like you, expect to DIY. You want to expand that constituency, use CMSIS register naming/access methods, or use the HAL or LL, until you can free climb

Read the manual and debug the code, that's what writing register level code entails.

Enable the GPIOA clock if you plan on using/configuring it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

2 REPLIES 2

There's about ONE person coding like you, expect to DIY. You want to expand that constituency, use CMSIS register naming/access methods, or use the HAL or LL, until you can free climb

Read the manual and debug the code, that's what writing register level code entails.

Enable the GPIOA clock if you plan on using/configuring it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi,

Yes, I forgot to enable clock to GPIOA. It works now.

Thanks