pihwm  r1
A lightweight C library for Raspberry Pi hardware modules.
pi_pwm.c
Go to the documentation of this file.
1 
28 /* Based on Gert van Loo's example code. */
29 
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <dirent.h>
34 #include <fcntl.h>
35 #include <assert.h>
36 #include <sys/mman.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <sys/time.h>
40 #include <unistd.h>
41 
42 #include "pihwm.h"
43 
44 // Registers
45 // FIXME: These are already defined in .h, remove?
46 volatile unsigned int *gpio, *pwm, *clk;
47 
58 static int
59 open_memory ()
60 {
61  int mem_fd;
62 
63  mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
64 
65  if ( mem_fd < 0 )
66  {
67  debug("[%s] Can't open /dev/mem. Are you root?\n", __func__);
68  return -1;
69  } else {
70  return mem_fd;
71  }
72 
73 }
74 
83 static volatile unsigned int*
84 map_register (int mem_fd, unsigned int addr)
85 {
86  char *mem;
87  unsigned char *map;
88 
89  // Allocate a chunk of memory
90  if ( (mem = malloc(BLOCK_SIZE + (PAGE_SIZE - 1))) == NULL )
91  {
92  debug("[%s] Can't allocate memory.\n", __func__);
93  return 0;
94  }
95 
96  // Align?
97  if ( (unsigned long) mem % PAGE_SIZE )
98  {
99  mem += PAGE_SIZE - ((unsigned long) mem % PAGE_SIZE);
100  }
101 
102  // Map relevant register address to the allocated memory pointer
103  map = (unsigned char *) mmap ((caddr_t) mem,
104  BLOCK_SIZE, PROT_READ | PROT_WRITE,
105  MAP_SHARED | MAP_FIXED, mem_fd, addr);
106 
107  if ( (long) map < 0 )
108  {
109  debug("[%s] Can't mmap memory.\n", __func__);
110  return 0;
111  } else {
112  return (volatile unsigned int*) map;
113  }
114 
115 }
116 
122 int
124 {
125 
126  int mem_fd;
127 
128  mem_fd = open_memory();
129  if ( mem_fd < 0)
130  {
131  debug("[%s] Can't open /dev/mem.\n", __func__);
132  return -1;
133  }
134 
135  // FIXME: Check return values?
136  gpio = map_register(mem_fd, GPIO_BASE);
137  clk = map_register(mem_fd, CLOCK_BASE);
138  pwm = map_register(mem_fd, PWM_BASE);
139 
140  /* GPIO18= PWM channel-A Funct. 5
141  Setup GPIO18 as PWM output */
142  INP_GPIO(18);
143  SET_GPIO_ALT(18, 5);
144 
145  /* Derive PWM clock direct from X-tal
146  thus any system auto-slow-down-clock-to-save-power does not effect it
147  The values below depends on the X-tal frequency! */
148  PWMCLK_DIV = 0x5A000000 | (32 << 12);/* set pwm div to 32 (19.2/3 = 600KHz) */
149  PWMCLK_CNTL = 0x5A000011; /* Source=osc and enable */
150 
151  /* Make sure it is off and that the B driver (GPIO4) is low */
152  GPIO_CLR0 = 1 << 4; /* Set GPIO 4 LOW */
153 
154  PWM_CONTROL = 0;
155  usleep(100);
156 
157  /* 1024 steps for the PWM */
158  PWM0_RANGE = PWM_MAX;
159  usleep(100);
160 
161  PWM_CONTROL = PWM0_ENABLE;
162  usleep(100);
163 
164  return 1;
165 
166 }
167 
175 void
176 pwm_mode (unsigned int mode)
177 {
178  PWM_CONTROL = mode;
179 }
180 
181 
189 void
190 pwm_value (unsigned int value)
191 {
192 
193  if ( value < 0 )
194  {
195  value = 0;
196  }
197 
198  if ( value > PWM_MAX )
199  {
200  value = PWM_MAX;
201  }
202 
203  PWM0_DATA = value;
204 }
205 
206 
212 void
214 {
215 
216  GPIO_CLR0 = 1 << 4;
217  pwm_value(0);
218  PWM_CONTROL = 0;
219 
220  // FIXME: Check this.
221  //munmap(pwm, BLOCK_SIZE);
222  //munmap(gpio, BLOCK_SIZE);
223  //munmap(clk, BLOCK_SIZE);
224 }
225 
void pwm_mode(unsigned int mode)
Sets mode for the PWM peripheral.
Definition: pi_pwm.c:176
int pwm_init()
Initialises the PWM peripheral.
Definition: pi_pwm.c:123
void pwm_release()
Releases the PWM peripheral and unmaps the memory.
Definition: pi_pwm.c:213
Header for general library functionality.
void pwm_value(unsigned int value)
Sets PWM value.
Definition: pi_pwm.c:190