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.

Dependencies:   mbed

Files at this revision

API Documentation at this revision

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