[2.0.x] Add support for LPC1769 at 120 MHz (#9423)

This commit is contained in:
Thomas Moore
2018-02-03 19:33:26 -06:00
committed by Scott Lahteine
parent 6ace57e1b0
commit e1fd9c08b3
19 changed files with 431 additions and 292 deletions

View File

@ -496,7 +496,20 @@ void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
break;
}
}
}
// detect 17x[4-8] (100MHz) or 17x9 (120MHz)
static int can_120MHz() {
#define IAP_LOCATION 0x1FFF1FF1
uint32_t command[1];
uint32_t result[5];
typedef void (*IAP)(uint32_t*, uint32_t*);
IAP iap = (IAP) IAP_LOCATION;
command[0] = 54;
iap(command, result);
return result[1] & 0x00100000;
}
/**
@ -508,7 +521,6 @@ void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
* @brief Setup the microcontroller system.
* Initialize the System.
*/
void SystemInit (void)
{
#if (CLOCK_SETUP) /* Clock Setup */
@ -546,9 +558,15 @@ void SystemInit (void)
LPC_SC->CCLKCFG = 0x00000002; /* Setup CPU Clock Divider */
LPC_SC->PLL0CFG = 0x00010018; // 100MHz
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;
if(can_120MHz()) {
LPC_SC->PLL0CFG = 0x0000000E; /* configure PLL0 */
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;
} else {
LPC_SC->PLL0CFG = 0x00010018; // 100MHz
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;
}
LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */
LPC_SC->PLL0FEED = 0xAA;

View File

@ -11,10 +11,12 @@
/
/-------------------------------------------------------------------------*/
#include "lpc17xx_ssp.h"
#include "lpc17xx_clkpwr.h"
#include "LPC176x.h"
#define SSP_CH 1 /* SSP channel to use (0:SSP0, 1:SSP1) */
#define CCLK 100000000UL /* cclk frequency [Hz] */
#define PCLK_SSP 50000000UL /* PCLK frequency to be supplied for SSP [Hz] */
#define SCLK_FAST 25000000UL /* SCLK frequency under normal operation [Hz] */
#define SCLK_SLOW 400000UL /* SCLK frequency under initialization [Hz] */
@ -55,21 +57,49 @@
}
#endif
#if PCLK_SSP * 1 == CCLK
#define PCLKDIV_SSP PCLKDIV_1
#elif PCLK_SSP * 2 == CCLK
#define PCLKDIV_SSP PCLKDIV_2
#elif PCLK_SSP * 4 == CCLK
#define PCLKDIV_SSP PCLKDIV_4
#elif PCLK_SSP * 8 == CCLK
#define PCLKDIV_SSP PCLKDIV_8
#else
#error Invalid CCLK:PCLK_SSP combination.
#endif
static void set_spi_clock(uint32_t target_clock)
{
uint32_t prescale, cr0_div, cmp_clk, ssp_clk;
/* The SSP clock is derived from the (main system oscillator / 2),
so compute the best divider from that clock */
#if SSP_CH == 0
ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP0);
#elif SSP_CH == 1
ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP1);
#endif
/* Find closest divider to get at or under the target frequency.
Use smallest prescale possible and rely on the divider to get
the closest target frequency */
cr0_div = 0;
cmp_clk = 0xFFFFFFFF;
prescale = 2;
while (cmp_clk > target_clock)
{
cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
if (cmp_clk > target_clock)
{
cr0_div++;
if (cr0_div > 0xFF)
{
cr0_div = 0;
prescale += 2;
}
}
}
/* Write computed prescaler and divider back to register */
SSPxCR0 &= (~SSP_CR0_SCR(0xFF)) & SSP_CR0_BITMASK;
SSPxCR0 |= (SSP_CR0_SCR(cr0_div)) & SSP_CR0_BITMASK;
SSPxCPSR = prescale & SSP_CPSR_BITMASK;
}
#define FCLK_FAST() { SSPxCR0 = (SSPxCR0 & 0x00FF) | ((PCLK_SSP / 2 / SCLK_FAST) - 1) << 8; }
#define FCLK_SLOW() { SSPxCR0 = (SSPxCR0 & 0x00FF) | ((PCLK_SSP / 2 / SCLK_SLOW) - 1) << 8; }
#define FCLK_FAST() set_spi_clock(SCLK_FAST)
#define FCLK_SLOW() set_spi_clock(SCLK_SLOW)
@ -79,7 +109,6 @@
---------------------------------------------------------------------------*/
#include "LPC176x.h"
#include "diskio.h"
@ -276,7 +305,6 @@ void power_on (void) /* Enable SSP module and attach it to I/O pads */
{
__set_PCONP(PCSSPx, 1); /* Enable SSP module */
__set_PCLKSEL(PCLKSSPx, PCLKDIV_SSP); /* Select PCLK frequency for SSP */
SSPxCPSR = 2; /* CPSDVSR=2 */
SSPxCR0 = 0x0007; /* Set mode: SPI mode 0, 8-bit */
SSPxCR1 = 0x2; /* Enable SSP with Master */
ATTACH_SSP(); /* Attach SSP module to I/O pads */