UART initialization stops application

Hi,

I have those;

LPC1769
FreeRTOS 10.3.2
UART1
And except UART1 init issue, the rest (uIP, Led flashing test, etc…) is working OK.

I believe that the problem must be obvious to some expert on FreeRTOS.
The issue is, at some point within UART1 initialization, application stops. If I read my debugger correctly, it falls in hard-fault (HFSR > Forced = 1).

Here is the method where UART1 initializes;
I call the init method in this order within main method;
prvSetupHardware();
uart1_init(38600);

	void uart1_init(uint32_t __baudrate)
	{
		uint32_t Fdiv;
		uint32_t pclkdiv, pclk;	

		PINCON->PINSEL4 &= ~0x0000000F;
		PINCON->PINSEL4 |= 0x0000000A; /* Enable RxD1 P2.1, TxD1 P2.0 */
        /* By default, the PCLKSELx value is zero, thus, the PCLK for
        all the peripherals is 1/4 of the SystemFrequency. */
        /* Bit 8,9 are for UART1 */
		pclkdiv = (SC->PCLKSEL0 >> 8) & 0x03;

		switch ( pclkdiv )
		{
			case 0x00:
			default:
				pclk = ( unsigned long ) 4000000UL / 4;
				break;
			case 0x01:
				pclk = ( unsigned long ) 4000000UL;
				break;
			case 0x02:
				pclk = ( unsigned long ) 4000000UL / 2;
				break;
			case 0x03:
				pclk = ( unsigned long ) 4000000UL / 8;
				break;
		}

    UART1->LCR = 0x83;		/* 8 bits, no Parity, 1 Stop bit */
	Fdiv = ( pclk / 16 ) / __baudrate ;	/*baud rate */
    UART1->DLM = Fdiv / 256;							
    UART1->DLL = Fdiv % 256;
	UART1->LCR = 0x03;		/* DLAB = 0 */
    UART1->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */

Using debugger I found out, it doesn’t go further than this line; UART1->DLM = Fdiv / 256;

You may find my FreeRTOSConfig.h attached in case of you may need to see some settings.
You may also ask some further code from the application.

EDIT:
I also add here hardware setup funtion.

void prvSetupHardware( void )
{   
	/* Disable peripherals power. */
	SC->PCONP = 0;

	/* Enable GPIO power. */
	SC->PCONP = PCONP_PCGPIO;

	/* Disable TPIU. */
	PINCON->PINSEL10 = 0;

	if ( SC->PLL0STAT & ( 1 << 25 ) )
	{
		/* Enable PLL, disconnected. */
		SC->PLL0CON = 1;
		SC->PLL0FEED = PLLFEED_FEED1;
		SC->PLL0FEED = PLLFEED_FEED2;
	}

	/* Disable PLL, disconnected. */
	SC->PLL0CON = 0;
	SC->PLL0FEED = PLLFEED_FEED1;
	SC->PLL0FEED = PLLFEED_FEED2;

 SC->SCS       =  (1<<5);            //enable main oscillator bit 5
 while ((SC->SCS & (1<<6)) == 0);/* Wait for Oscillator to be ready    */
 
	/* Enable main OSC. ORIGINAL */ 
//	SC->SCS |= 0x20;
//	while( !( SC->SCS & 0x40 ) );

	/* select main OSC, 12MHz, as the PLL clock source. */
	SC->CLKSRCSEL = 0x1;

	SC->PLL0CFG = 0x00050077; //0x20031;
    
	SC->PLL0FEED = PLLFEED_FEED1;
	SC->PLL0FEED = PLLFEED_FEED2;

	/* Enable PLL, disconnected. */
	SC->PLL0CON = 1;
	SC->PLL0FEED = PLLFEED_FEED1;
	SC->PLL0FEED = PLLFEED_FEED2;

	/* Set clock divider. */
	SC->CCLKCFG = 0x03;

	/* Configure flash accelerator. */
	SC->FLASHCFG = 0x403a;

	/* Check lock bit status. */
	while( ( ( SC->PLL0STAT & ( 1 << 26 ) ) == 0 ) );

	/* Enable and connect. */
	SC->PLL0CON = 3;
	SC->PLL0FEED = PLLFEED_FEED1;
	SC->PLL0FEED = PLLFEED_FEED2;
	while( ( ( SC->PLL0STAT & ( 1 << 25 ) ) == 0 ) );

	/* Configure the clock for the USB. */

	if( SC->PLL1STAT & ( 1 << 9 ) )
	{
		/* Enable PLL, disconnected. */
		SC->PLL1CON = 1;
		SC->PLL1FEED = PLLFEED_FEED1;
		SC->PLL1FEED = PLLFEED_FEED2;
	}

	/* Disable PLL, disconnected. */
	SC->PLL1CON = 0;
	SC->PLL1FEED = PLLFEED_FEED1;
	SC->PLL1FEED = PLLFEED_FEED2;

	SC->PLL1CFG = 0x23;
	SC->PLL1FEED = PLLFEED_FEED1;
	SC->PLL1FEED = PLLFEED_FEED2;

	/* Enable PLL, disconnected. */
	SC->PLL1CON = 1;
	SC->PLL1FEED = PLLFEED_FEED1;
	SC->PLL1FEED = PLLFEED_FEED2;
	while( ( ( SC->PLL1STAT & ( 1 << 10 ) ) == 0 ) );

	/* Enable and connect. */
	SC->PLL1CON = 3;
	SC->PLL1FEED = PLLFEED_FEED1;
	SC->PLL1FEED = PLLFEED_FEED2;
	while( ( ( SC->PLL1STAT & ( 1 << 9 ) ) == 0 ) );

	/*  Setup the peripheral bus to be the same as the CPU output (100 MHz). */
	SC->PCLKSEL0 = 0x05555555;

	/* Configure the LEDs. */
	vParTestInitialise();
        
    //Piezoelectric Buzzer
    GPIO2->FIODIR |= (0x1<<4); /* P2.4 defined as Outputs */
    GPIO2->FIOCLR = (0x1<<4);  /* Set it LOW so it won't make noise at the begining */
}

I appreciate your inputs from now.
Best Regards,
Sener

FreeRTOSConfig.h (6.5 KB)

Are you initialising the UART before starting the FreeRTOS scheduler? If so then I doubt there will be anything in the FreeRTOSConfig.h that will impact you. One of the things to watch out for is that the interrupt handler for the uart does not execute too soon if it tries to use the FreeRTOS API before FreeRTOS has been started.

And verify that __baudrate is already initialized i.e. is not 0.

@rtel, Yes, I do initialize UART before FreeRTOS scheduler. And the interrupt related setup comes right after the code I mentioned in my post. So, there is no interrupt yet at that moment.
Normally that code comes after;

NVIC_EnableIRQ(UART1_IRQn);
UART1->IER = IER_RBR | IER_RLS; /* Enable UART1 interrupt */

However, although there is a breakpoint at the beginning of this interrupt enabling code, it never gets hit.

@hs2, no, it is not 0, it is 38600.

I have this figures in place;

pclk = 4000000
Fdiv = ( pclk / 16 ) / __baudrate = 6 => This line passess safe and sound but stucks in the next which is UART1->DLM = Fdiv / 256;

That’s really weird. There is no obvious problem as far as I can see.
I guess UART1 is a CMSIS defined pointer to the absolute HW address of the peripheral.
Accessing it’s DLM register can’t fail…
When it comes to this kind of magic it’s time to single step through the assembler instructions until it breaks watching the registers to get an idea what’s going wrong.

@hs2, UART1 is a macro defined like that #define UART1 (( UART1_TypeDef *) UART1_BASE) in LPC17xx.h

If I step through in the assembler instructions it stuck at the same place as I pointed in my post. I squared the instruction where I could go maximum.

image

I think it’s the BLX jump which HardFaults. Guessing that the EQ condition (bit) is not set in the ARM core CPSR register (can be verified with debugger) by the ORRCS instruction the following EORSEQ conditional instruction is skipped.
You could also try to set the PC at the BLX instruction manually with the debugger and do the next step.
… google… (hope I’m right) the BLX label instruction in turn changes the processor state from thumb to ARM which causes the HardFault.
Do you specify the correct compiler flags -mcpu=cortex-m3 -mthumb ?
That should avoid generating BLX instructions.

@hs2, I don’t know how reliable solution is but, I replaced prvSetupHardware(); with those two lines;

SystemInit();
SystemCoreClockUpdate();

And now uart1_init(38600); passes OK, application continues.

This doesn’t mean UART works OK entirely but initializes.

I use IAR Workbench. I build within the IDE. I dont’ supply extra flags other than choosing target device.