[SOLVED] LPC1778 hard fault during UART setup

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by dbtayl on Sat Oct 25 13:38:57 MST 2014
SOLVED! The issue was my linker command line not including "-mcpu=cortex-m3 -mthumb". This was causing GCC to link in the ARM version of libgcc.a instead of the Thumb version. Since the Cortex M3 can't execute ARM instructions, this caused the issues I was experiencing.

I'm trying to get the MCI and UARTs working on my LPC1778 board. The board is one I designed and built myself, and physically it seems to function fine. I can use timers and toggle GPIOs, but am getting some really weird behavior with trying to configure the UARTs and MCI.

I'm using GCC-ARM-Embedded 4.8-2014-q3-update (also tried with 4.8-2013-q4 and 4.6-2012-something) under Linux, with no IDE (just a Makefile and lpc21isp to program with a USB-serial adapter).

Here's what happens: I try to initialize the UART, and it just... freezes during the UART_Init call (more specifically, in the uart_set_divisors function within that call). By adding code to toggle a GPIO and moving it around until things fail, I've narrowed it down to the code failing on this line in uart_set_divisors (about line 145 in lpc177x_8x_uart.c):

//Code executes to here

/* can not find best match */
if(best_divisor == 0)
    //...but not here
    return ERROR;

//...or here

Which makes no sense to me, since it should make it to ONE of those points, and it's not like there's a possible divide-by-zero or some such.

My main function:
int main()
TIM_TIMERCFG_Type tinit;
tinit.PrescaleOption = TIM_PRESCALE_TICKVAL;
tinit.PrescaleValue = 12; //12 seems to be the correct value for 24 MHz


GPIO_SetDir(4, 1<<5, GPIO_DIRECTION_OUTPUT); //LCD reset line

//Try to set up UART
UART_CFG_Type cfg;

    //setting these to '2' gives UART3 control of p0[2,3]
PINSEL_ConfigPin(0, 2, 2);
PINSEL_ConfigPin(0, 3, 2);


UART_Init(UART_3, &cfg); //this never returns

UART_FIFOConfig(UART_3, &UARTFIFOConfigStruct);

//should get here and loop forever
LPC_GPIO4->SET = 1<<5;
char buf[] = "foobar\n";
LPC_GPIO4->CLR = 1<<5;
UART_SendByte(UART_3,  0x55);

return 0;

Only changed section in system_LPC177x_8x.c:
#define CLOCK_SETUP           1
//#define SCS_Val               0x00000021
//0000 Changed to disable use of main oscillator- we don't have one!
#define SCS_Val               0x00000001

//0000 Again, changed to use the internal RC oscillator
//#define CLKSRCSEL_Val         0x00000001
#define CLKSRCSEL_Val         0x00000000
#define PLL0_SETUP            1
#define PLL0CFG_Val           0x00000009
//#define PLL0CFG_Val           0x00000002
//0000 Don't use PLL1 with internal RC oscillator
//#define PLL1_SETUP            1
#define PLL1_SETUP            0
#define PLL1CFG_Val           0x00000023
//0000 Try using sysclk directly, without the PLL
//#define CCLKSEL_Val           0x00000101
#define CCLKSEL_Val           0x00000001
#define USBCLKSEL_Val         0x00000201
#define EMCCLKSEL_Val         0x00000001
#define PCLKSEL_Val           0x00000002
#define PCONP_Val             0x042887DE
#define CLKOUTCFG_Val         0x00000100

Full code is attached. There are a bunch of extra files that can be ignored (ili9325*, map_*, gps_* font*, ...; basically main.c and the files listed above are all that I've mucked with).

There's no crystal attached to the chip, so I'm using the onboard oscillator. I've tried adjusting the frequency (slowing things down), not using the PLL, and compiling without optimizations, all with the same result as noted above. I've also assembled a second board that exhibits the exact same problems as the first, so either it's a highly-specific and very coincidental hardware failure, or the hardware is fine.

I suppose it's also possible I messed something up on my board layout, but I don't see how that would cause the hangup where I'm seeing it. Board schematic is attached, in case that's helpful.

For debugging, I've got access to a multimeter and an oscilloscope. And a USB-serial adapter, obviously, but that doesn't do much good when the UART isn't working.

Any help would be much appreciated. I'm completely baffled as to why things would fail in such a manner.

Thanks in advance.

EDIT: I've since determined that the code is going to the hard fault handler, for no reason as far as I can tell.

Original Attachment has been moved to: uart_test_code.tar.gz