Skip to content

Instantly share code, notes, and snippets.

@katogiso
Created November 5, 2017 06:39
Show Gist options
  • Save katogiso/9ce0af6bfb3f129153864052f01cb849 to your computer and use it in GitHub Desktop.
Save katogiso/9ce0af6bfb3f129153864052f01cb849 to your computer and use it in GitHub Desktop.
RaspberryPi pwm sample
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#define PERI_BASE 0x3F000000
#define GPIO_BASE (PERI_BASE + 0x200000)
#define PWM_BASE (PERI_BASE + 0x20C000)
#define CLK_BASE (PERI_BASE + 0x101000)
#define CLK_PASSWD 0x5A000000
#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)
// I/O access
volatile unsigned *gpio;
volatile unsigned *pwm;
volatile unsigned *clk;
static int mem_fd = 0;
void check( int condition, char* msg )
{
if( condition ){ printf("%s", msg); exit (-1);}
}
volatile unsigned * io_mapping(int base_addr)
{
char *gpio_mem, *gpio_map;
if (!mem_fd) {
mem_fd = open("/dev/mem", O_RDWR|O_SYNC);
check((mem_fd < 0), "can't open /dev/mem \n");
}
gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1));
check( ( gpio_mem == NULL), "allocation error \n");
// Make sure pointer is on 4K boundary
if ((unsigned long) gpio_mem % PAGE_SIZE)
gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE);
// Now map it
gpio_map = (char *)mmap((caddr_t)gpio_mem,
BLOCK_SIZE,
PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_FIXED,
mem_fd,
base_addr );
check( ((long)gpio_map < 0), "mmap error \n");
return (volatile unsigned *)gpio_map;
}
void main()
{
//------------------------------------
// set GPIO18 mode to ALT5(PWM0)
//------------------------------------
gpio = io_mapping(GPIO_BASE);
*(gpio + 0x4/4) = (*(gpio + 0x4/4) & ~(0x7 << 24 )) | (0b010 << 24);
//------------------------------------
// set source clock
//------------------------------------
clk = io_mapping(CLK_BASE);
clk += 0xA0/4;
// Oscillator 19.2MHz
*clk = CLK_PASSWD + (0x1<<5);
*(clk+0x4/4) = CLK_PASSWD + (192 << 12);
*clk = CLK_PASSWD + 0x1 + (0x1 << 4);
//------------------------------------
// set pwm
//------------------------------------
pwm = io_mapping(PWM_BASE);
*pwm = 0; // Disable
usleep(10); // wait for stable
*(pwm + 0x10/4) = 4; // set RNG
*(pwm + 0x14/4) = 2; // set DAT
*pwm = 0x1; // Enable
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment