
Fast 20MHz PWM, with double edge controlled PWMs (90° Phase shifted). CPU clock had to be adjusted to 80MHz (PLL-controlled). Done by accessing the registers directrly.
Revision 0:8bd0ebc5cbb0, committed 2010-06-09
- Comitter:
- cedes
- Date:
- Wed Jun 09 07:47:00 2010 +0000
- Commit message:
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
mbed.bld | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 8bd0ebc5cbb0 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Jun 09 07:47:00 2010 +0000 @@ -0,0 +1,116 @@ +#include "mbed.h" + +DigitalOut myled1(LED1); +DigitalOut myled2(LED2); +DigitalOut myled3(LED3); +DigitalOut myled4(LED4); + +DigitalOut outGND1(p21); +PwmOut fmclck6(p22); +PwmOut fmclck5(p23); +DigitalOut outGND2(p24); +PwmOut fmclck4(p25); + +#define PLL0CFG_Val 0x00027 +#define PLL1_SETUP 0 +#define CCLKCFG_Val 5 +#define WAIT_SEC_BEFORE_START 5.0 + +int main() { + // Wait a bit before changing the clock. Who knows, perhaps + // it is needed to connect to the device + myled1 = 1; + wait(WAIT_SEC_BEFORE_START/4.0); + myled1 = 0; + myled2 = 1; + wait(WAIT_SEC_BEFORE_START/4.0); + myled2 = 0; + myled3 = 1; + wait(WAIT_SEC_BEFORE_START/4.0); + myled3 = 0; + myled4 = 1; + wait(WAIT_SEC_BEFORE_START/4.0); + myled1 = 1; + myled2 = 1; + myled3 = 1; + myled4 = 1; + + + + // The following sequence must be followed step by step in order to have PLL0 initialized + // and running: + + // 1. Disconnect PLL0 with one feed sequence if PLL0 is already connected. + LPC_SC->PLL0CON &= ~0x02; /* PLL0 Disconnect */ + LPC_SC->PLL0FEED = 0xAA; + LPC_SC->PLL0FEED = 0x55; + + // 2. Disable PLL0 with one feed sequence. + LPC_SC->PLL0CON &= ~0x01; /* PLL0 Disable */ + LPC_SC->PLL0FEED = 0xAA; + LPC_SC->PLL0FEED = 0x55; + + // 3. Change the CPU Clock Divider setting to speed up operation without PLL0, if desired. +// LPC_SC->CCLKCFG = 2; /* Setup Clock Divider "2 + 1 = 3 DIVIDER" */ + + // 4. Write to the Clock Source Selection Control register to change the clock source if + // needed. + LPC_SC->CLKSRCSEL = 0x00000001; /* Select Clock Source for PLL0 */ + + // 5. Write to the PLL0CFG and make it effective with one feed sequence. The PLL0CFG + // can only be updated when PLL0 is disabled. + LPC_SC->PLL0CFG = 0x00000013; /* configure PLL0, N = 1, M = 20 (0x13 + 1) */ + LPC_SC->PLL0FEED = 0xAA; + LPC_SC->PLL0FEED = 0x55; + + // 6. Enable PLL0 with one feed sequence. + LPC_SC->PLL0CON |= 0x01; /* PLL0 Enable */ + LPC_SC->PLL0FEED = 0xAA; + LPC_SC->PLL0FEED = 0x55; + + // 7. Change the CPU Clock Divider setting for the operation with PLL0. It is critical to do + // this before connecting PLL0. + LPC_SC->CCLKCFG = 5; /* Setup Clock Divider "5 + 1 = 6 DIVIDER" */ + + // 8. Wait for PLL0 to achieve lock by monitoring the PLOCK0 bit in the PLL0STAT register, + // or using the PLOCK0 interrupt, or wait for a fixed time when the input clock to PLL0 is + // slow (i.e. 32 kHz). The value of PLOCK0 may not be stable when the PLL reference + // frequency (FREF, the frequency of REFCLK, which is equal to the PLL input + // frequency divided by the pre-divider value) is less than 100 kHz or greater than + // 20 MHz. In these cases, the PLL may be assumed to be stable after a start-up time + // has passed. This time is 500 μs when FREF is greater than 400 kHz and 200 / FREF + // seconds when FREF is less than 400 kHz. + while (!(LPC_SC->PLL0STAT & (1<<26))); /* Wait for PLOCK0 */ + + // 9. Connect PLL0 with one feed sequence. + LPC_SC->PLL0CON |= 0x02; /* PLL0 Connect */ + LPC_SC->PLL0FEED = 0xAA; + LPC_SC->PLL0FEED = 0x55; + + // It is very important not to merge any steps above. For example, do not update the + // PLL0CFG and enable PLL0 simultaneously with the same feed sequence. + + + + // set PWM + outGND1 = 0; // Just to have a GND near to the PWMs + outGND2 = 0; // Just to have a GND near to the PWMs + LPC_PWM1->TCR = (1 << 1); // Reset counter, disable PWM + LPC_SC->PCLKSEL0 &= ~(0x3 << 12); + LPC_SC->PCLKSEL0 |= (1 << 12); // Set peripheral clock divider to /1, i.e. system clock + + LPC_PWM1->PCR |= 0x002C; // Double edge PWM for PWM2,3,5 + + LPC_PWM1->MR0 = 3; // Match Register 0 is shared period counter for all PWM1 + + LPC_PWM1->MR1 = 0; // so Match Register 0 + LPC_PWM1->MR2 = 2; // so Match Register 1 + LPC_PWM1->MR3 = 0; // so Match Register 2 + LPC_PWM1->MR4 = 1; // so Match Register 3 + LPC_PWM1->MR5 = 3; // so Match Register 3 + + LPC_PWM1->LER |= 1; // Start updating at next period start + LPC_PWM1->TCR = (1 << 0) || (1 << 3); // Enable counter and PWM + + while(1); +}
diff -r 000000000000 -r 8bd0ebc5cbb0 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Jun 09 07:47:00 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/029aa53d7323