#include #include #include #include #include #include #include #include #include #define PG_SZ 0x1000 #define PAD_CONF_BASE 0x48002000 #define PWM_PAD_9 0x0B4 #define PAD_MUX_MODE_3 3 #define TIMER_9_BASE 0x49040000 #define TIMER_TCLR 0x24 #define TIMER_START 1 #define TIMER_AUTORELOAD 2 #define TIMER_CE (1<<6) #define TIMER_SCPWM (1<<7) #define TIMER_PT (1<<12) #define TIMER_TRG (2<<10) #define TIMER_TCCR 0x28 #define TIMER_TLDR 0x2c #define TIMER_TMAR 0x38 #define CLK_BASE 0x48005000 #define EN_GPT9 (1<<10) #define CLKSEL_GPT9 (1<<7) #define SYS_CLK 26000000UL static int keep_running = 1; void sighandler(int sig) { keep_running = 0; } /* FREQUENCY = GPTi_FCLK / ((0xFFFF FFFF - TLDR) + 1) * TLDR = (0xFFFF FFFF - (GPTi_FCLK / FREQUENCY)) + 1 * NUM_SETTINGS = 0xFFFF FFFE - TLDR * TMAR = TLDR + (NUM_SETTINGS * DUTY_CYCLE_PERCENTAGE) */ int main(int argc, char *argv[]) { uintptr_t timer_ptr; uint32_t tmp32, tldr, tmar, num_settings, freq_khz = 1, duty_cycle_percentage = 50; char opt; while((opt = getopt(argc, argv, "f:p:")) != -1) { switch(opt) { case 'f': freq_khz = atoi(optarg); break; case 'p': duty_cycle_percentage = atoi(optarg); break; } } tldr = (0xffffffff - (SYS_CLK / (freq_khz * 1000))) + 1; num_settings = 0xfffffffe - tldr; tmar = tldr + ( (num_settings * duty_cycle_percentage) / 100 ); // set up the output pad timer_ptr = mmap_device_io(PG_SZ, PAD_CONF_BASE); tmp32 = in32(timer_ptr + PWM_PAD_9); tmp32 &= 0xffff; tmp32 |= (PAD_MUX_MODE_3<<16); out32(timer_ptr + PWM_PAD_9, tmp32); munmap_device_io(timer_ptr, PG_SZ); // turn on the clocks timer_ptr = mmap_device_io(PG_SZ, CLK_BASE); tmp32 = in32(timer_ptr); tmp32 |= EN_GPT9; out32(timer_ptr, tmp32); tmp32 = in32(timer_ptr + 0x10); tmp32 |= EN_GPT9; out32(timer_ptr + 0x10, tmp32); tmp32 = in32(timer_ptr + 0x40); tmp32 |= CLKSEL_GPT9; out32(timer_ptr + 0x40, tmp32); // select sys clock munmap_device_io(timer_ptr, PG_SZ); // set up the timer timer_ptr = mmap_device_io(PG_SZ, TIMER_9_BASE); out32(timer_ptr + TIMER_TCLR, 0); // disable //out32(timer_ptr + TIMER_TLDR, tldr); out32(timer_ptr + TIMER_TLDR, 0xffffffe0); //out32(timer_ptr + TIMER_TMAR, tmar); out32(timer_ptr + TIMER_TMAR, 0xffffffef); //out32(timer_ptr + TIMER_TCCR, tldr); out32(timer_ptr + TIMER_TCCR, 0xffffffe0); tmp32 = TIMER_START | TIMER_AUTORELOAD | TIMER_PT | TIMER_TRG | TIMER_CE | TIMER_SCPWM; out32(timer_ptr + TIMER_TCLR, tmp32); signal(SIGINT, sighandler); signal(SIGTERM, sighandler); while (keep_running) { printf("%x\n", in32(timer_ptr + TIMER_TCCR)); sleep(1); } // clean up munmap_device_io(timer_ptr, PG_SZ); return EXIT_SUCCESS; }