sett_pll invokes HardFault Handler

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

sett_pll invokes HardFault Handler

319 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by masterboy on Thu Nov 21 06:37:48 MST 2013
Hi all,

I have a problem. I try program lpc812 and I would like to change cpu clock with IRC. I have simple example:

#ifdef __USE_CMSIS
#include "LPC8xx.h"
#endif

#include <cr_section_macros.h>

typedef struct _PWRD {
void (*set_pll)(unsigned int cmd[], unsigned int resp[]);
void (*set_power)(unsigned int cmd[], unsigned int resp[]);
} PWRD;

typedef struct _ROM {
const PWRD * pWRD;
} ROM;

ROM ** rom = (ROM **) (0x1FFF1FF8 + 3 * sizeof(ROM**));

unsigned int command[4], result[2];

int main(void) {

__disable_irq();
LPC_SYSCON->SYSPLLCLKSEL = 0;
LPC_SYSCON->SYSPLLCLKUEN = 0;
LPC_SYSCON->SYSPLLCLKUEN = 1;
LPC_SYSCON->SYSAHBCLKDIV = 1;
command[0] = 12000;
command[1] = 24000;
command[2] = 0;
command[3] = 0;
(*rom)->pWRD->set_pll(command, result);
__enable_irq();

    while(1) {
    }
    return 0 ;
}



This code still causes HardFault Handler, but I don't know why Help please.
Labels (1)
0 Kudos
2 Replies

246 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by masterboy on Fri Nov 22 06:33:55 MST 2013
Thank you!!! This solution works :) The mistake is in the UM10601.

TO NXP SUPPORT: PLEASE FIX IT !

I have a next question. Can I set the CPU frequency to 30 MHz using IRC? Using the API can be set only 24 MHz.
0 Kudos

246 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wellsk on Thu Nov 21 09:40:00 MST 2013
I've used this with LPCOpen and it seems to work fine. Maybe the pointer value for ROM is wrong?

Here is the LPCOpen code for reference (not only ROM API structures and defines are included here). I'll apologize in advance for any syntax or cut/paste errors, but I hope it helps...

/**
 * @brief LPC8xx Power ROM APIs - set_pll mode options
 */
#define CPU_FREQ_EQU    0
#define CPU_FREQ_LTE    1
#define CPU_FREQ_GTE    2
#define CPU_FREQ_APPROX 3

/**
 * @brief LPC8xx Power ROM APIs - set_pll response0 options
 */
#define PLL_CMD_SUCCESS    0
#define PLL_INVALID_FREQ   1
#define PLL_INVALID_MODE   2
#define PLL_FREQ_NOT_FOUND 3
#define PLL_NOT_LOCKED     4

/**
 * @brief LPC8xx Power ROM APIs - set_power mode options
 */
#define PWR_DEFAULT         0
#define PWR_CPU_PERFORMANCE 1
#define PWR_EFFICIENCY      2
#define PWR_LOW_CURRENT     3

/**
 * @brief LPC8xx Power ROM APIs - set_power response0 options
 */
#define PWR_CMD_SUCCESS  0
#define PWR_INVALID_FREQ 1
#define PWR_INVALID_MODE 2

/**
 * @brief LPC8XX Power ROM API structure
 */
typedef struct PWRD_API {
void (*set_pll)(uint32_t cmd[], uint32_t resp[]);/*!< Set PLL function */
void (*set_power)(uint32_t cmd[], uint32_t resp[]);/*!< Set power function */
} PWRD_API_T;

/**
 * @brief LPC8XX High level ROM API structure
 */
typedef struct ROM_API {
const uint32_t    unused[3];
const PWRD_API_T  *pPWRD;/*!< Power profiles API function table */
const uint32_t    p_dev1;
const I2CD_API_T  *pI2CD;/*!< I2C driver routines functions table */
const uint32_t    p_dev3;
const uint32_t    p_dev4;
const uint32_t    p_dev5;
const UARTD_API_T *pUARTD;/*!< UART driver routines function table */
} ROM_API_T;

#define ROM_DRIVER_BASE (0x1FFF1FF8UL)

#define LPC_PWRD_API    ((PWRD_API_T *) ((*(ROM_API_T * *) (ROM_DRIVER_BASE))->pPWRD))
#define LPC_I2CD_API    ((I2CD_API_T *) ((*(ROM_API_T * *) (ROM_DRIVER_BASE))->pI2CD))
#define LPC_UART_API    ((UARTD_API_T *) ((*(ROM_API_T * *) (ROM_DRIVER_BASE))->pUARTD))



And here is how the code is used:
/* Setup system clocking */
#define USE_ROM_API
#define LPC8XX_USE_XTAL_OSC
void SystemSetupClocking(void)
{
#if defined (USE_ROM_API)
uint32_t cmd[4], resp[2];
#endif

#if (LPC8XX_USE_XTAL_OSC == 1)
/* EXT oscillator < 15MHz */
Chip_Clock_SetPLLBypass(false, false);

/* Turn on the SYSOSC by clearing the power down bit */
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_SYSOSC_PD);

/* Select the PLL input to the external oscillator */
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_SYSOSC);

#else
/* Turn on the IRC by clearing the power down bit */
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_IRC_PD);

/* Select the PLL input in the IRC */
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_IRC);
#endif /* (LPC8XX_USE_XTAL_OSC == 1) */

/* Setup FLASH access to 2 clocks (up to 30MHz) */
Chip_FMC_SetFLASHAccess(FLASHTIM_30MHZ_CPU);

#if defined (USE_ROM_API)
#if (LPC8XX_USE_XTAL_OSC == 1)
/* Use ROM API for setting up PLL */
cmd[0] = Chip_Clock_GetMainOscRate() / 1000; /* in KHz */
#else
cmd[0] = Chip_Clock_GetIntOscRate() / 1000; /* in KHz */
#endif
cmd[1] = 24000000 / 1000; /* 24MHz system clock rate */
cmd[2] = CPU_FREQ_EQU;
cmd[3] = 24000000 / 10000;
LPC_PWRD_API->set_pll(cmd, resp);

/* Dead loop on fail */
while (resp[0] != PLL_CMD_SUCCESS) {}

#else
/* Power down PLL to change the PLL divider ratio */
Chip_SYSCTL_PowerDown(SYSCTL_SLPWAKE_SYSPLL_PD);

/* Configure the PLL M and P dividers */
/* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 2 = 324Hz
   MSEL = 1 (this is pre-decremented), PSEL = 2 (for P = 4)
   FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 2 = 24MHz
   FCCO = FCLKOUT * 2 * P = 24MHz * 2 * 4 = 192MHz (within FCCO range) */
Chip_Clock_SetupSystemPLL(1, 2);

/* Turn on the PLL by clearing the power down bit */
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_SYSPLL_PD);

/* Wait for PLL to lock */
while (!Chip_Clock_IsSystemPLLLocked()) {}

/* Set system clock divider to 1 */
Chip_Clock_SetSysClockDiv(1);

/* Set main clock source to the system PLL. This will drive 24MHz
   for the main clock and 24MHz for the system clock */
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_PLLOUT);
#endif
}


0 Kudos