This is still partly based on guesswork, as not all of this is properly documented in the data sheets, so if anyone has any suggestions for corrections, do post them.
This is the code I have for starting up PWM. It is written for bare metal mode, thus the direct memory accesses, but it should be easy enough to adapt to Linux if you just mmap() /dev/mem as usual:
Code: Select all
#define PWMCTL (*(volatile uint32_t *)0x2020c000)
#define PWMSTA (*(volatile uint32_t *)0x2020c004)
#define PWMDMAC (*(volatile uint32_t *)0x2020c008)
#define PWMRNG1 (*(volatile uint32_t *)0x2020c010)
#define PWMDAT1 (*(volatile uint32_t *)0x2020c014)
#define PWMFIF1 (*(volatile uint32_t *)0x2020c018)
#define PWMRNG2 (*(volatile uint32_t *)0x2020c020)
#define PWMDAT2 (*(volatile uint32_t *)0x2020c024)
#define CM_PWMCTL (*(volatile uint32_t *)0x201010a0)
#define CM_PWMDIV (*(volatile uint32_t *)0x201010a4)
PWMCTL=0; // Turn off PWM.
CM_PWMCTL=(CM_PWMCTL&~0x10)|0x5a000000; // Turn off enable flag.
while(CM_PWMCTL&0x80); // Wait for busy flag to turn off.
CM_PWMDIV=0x5a000000|(5<<12); // Configure divider.
CM_PWMCTL=0x5a000206; // Source=PLLD (500 MHz), 1-stage MASH.
CM_PWMCTL=0x5a000216; // Enable clock.
while(!(CM_PWMCTL&0x80)); // Wait for busy flag to turn on.
PWMRNG1=100;
PWMDAT1=10;
PWMCTL=0x0081; // Channel 1 M/S mode, no FIFO, PWM mode, enabled.
This seems to me to be the correct way to configure the clock, but if anyone has any problems with it, do tell.
Relatedly, here is how to set up the GPIO clock to output a clock signal on one of the GPIO pins, if you want to play with the FM transmission tricks or something:
Code: Select all
#define CM_GP0CTL (*(volatile uint32_t *)0x20101070)
#define CM_GP0DIV (*(volatile uint32_t *)0x20101074)
CM_GP0CTL=CM_GP0CTL&~0x10; // Turn off enable flag.
while(CM_GP0CTL&0x80); // Wait for busy flag to turn off.
CM_GP0DIV=0x5a000000|(10<<12); // Configure divider.
CM_GP0CTL=0x5a000206; // Source=PLLD (500 MHz), 1-stage MASH.
CM_GP0CTL=0x5a000216; // Enable clock.
while(!(CM_GP0CTL&0x80)); // Wait for busy flag to turn on.
SetGPIOAlternateMode(4,0);
Edit: Fixed a line in the "Turn off enable flag" line to properly include the password.
