00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <sys/mman.h>
00012 #include "korebot.h"
00013 #include "kb_pxa_register.h"
00014 #include "kb_gpio.h"
00015
00016
00031 #define MAP_SIZE 4096UL
00032 #define MAP_MASK (MAP_SIZE - 1)
00033
00034 #define MEMDEV "/dev/mem"
00035 #define MAXPWM 2
00036
00037 #define PWM0 16
00038 #define PWM1 17
00039
00040 #define reg_val(reg) *((unsigned long *)reg)
00041
00042 static void* map_base_pwm0;
00043 static void* map_base_pwm1;
00044
00045 static void* map_base_clk;
00046 static int fd_pwm0;
00047 static int fd_pwm1;
00048 static int fd_clk;
00049
00050
00051
00052 static void bit_set_pwm0(unsigned long addr,unsigned gpio)
00053 {
00054 void * virt_addr;
00055 unsigned long mask;
00056
00057 virt_addr = map_base_pwm0 + ((addr+(gpio/32)*4) & MAP_MASK);
00058
00059 mask = 1 << (gpio%32);
00060
00061 reg_val(virt_addr) = reg_val(virt_addr) | mask;
00062 }
00063
00064 static void bit_clear_pwm0(unsigned long addr,unsigned gpio)
00065 {
00066 void * virt_addr;
00067 unsigned long mask;
00068
00069 virt_addr = map_base_pwm0 + ((addr+(gpio/32)*4) & MAP_MASK);
00070 mask = 1 << (gpio%32);
00071
00072 reg_val(virt_addr) = reg_val(virt_addr) & ~mask;
00073 }
00074
00075 static int bit_test_pwm0(unsigned long addr,unsigned gpio)
00076 {
00077 void * virt_addr;
00078 unsigned long mask;
00079
00080 virt_addr = map_base_pwm0 + ((addr+(gpio/32)*4) & MAP_MASK);
00081 mask = 1 << (gpio%32);
00082
00083 if(reg_val(virt_addr) & mask)
00084 return 1;
00085 else
00086 return 0;
00087 }
00088
00089 static void reg_set_pwm0(unsigned long addr,unsigned long value)
00090 {
00091 void * virt_addr;
00092
00093 virt_addr = map_base_pwm0 + (addr & MAP_MASK);
00094
00095 reg_val(virt_addr) = value;
00096 }
00097
00098 static long int get_reg_pwm0(unsigned long addr)
00099 {
00100 void * virt_addr;
00101
00102 virt_addr = map_base_pwm0 + (addr & MAP_MASK);
00103
00104 return reg_val(virt_addr);
00105 }
00106
00107
00108
00109
00110 static void bit_set_pwm1(unsigned long addr,unsigned gpio)
00111 {
00112 void * virt_addr;
00113 unsigned long mask;
00114
00115 virt_addr = map_base_pwm1 + ((addr+(gpio/32)*4) & MAP_MASK);
00116
00117 mask = 1 << (gpio%32);
00118
00119 reg_val(virt_addr) = reg_val(virt_addr) | mask;
00120 }
00121
00122 static void bit_clear_pwm1(unsigned long addr,unsigned gpio)
00123 {
00124 void * virt_addr;
00125 unsigned long mask;
00126
00127 virt_addr = map_base_pwm1 + ((addr+(gpio/32)*4) & MAP_MASK);
00128 mask = 1 << (gpio%32);
00129
00130 reg_val(virt_addr) = reg_val(virt_addr) & ~mask;
00131 }
00132
00133 static int bit_test_pwm1(unsigned long addr,unsigned gpio)
00134 {
00135 void * virt_addr;
00136 unsigned long mask;
00137
00138 virt_addr = map_base_pwm1 + ((addr+(gpio/32)*4) & MAP_MASK);
00139 mask = 1 << (gpio%32);
00140
00141 if(reg_val(virt_addr) & mask)
00142 return 1;
00143 else
00144 return 0;
00145 }
00146
00147 static void reg_set_pwm1(unsigned long addr,unsigned long value)
00148 {
00149 void * virt_addr;
00150
00151 virt_addr = map_base_pwm1 + (addr & MAP_MASK);
00152
00153 reg_val(virt_addr) = value;
00154 }
00155
00156 static long int get_reg_pwm1(unsigned long addr)
00157 {
00158 void * virt_addr;
00159
00160 virt_addr = map_base_pwm1 + (addr & MAP_MASK);
00161
00162 return reg_val(virt_addr);
00163 }
00164
00165
00166
00167
00168 static void bit_set_clk(unsigned long addr,unsigned gpio)
00169 {
00170 void * virt_addr;
00171 unsigned long mask;
00172
00173 virt_addr = map_base_clk + ((addr+(gpio/32)*4) & MAP_MASK);
00174
00175 mask = 1 << (gpio%32);
00176
00177 reg_val(virt_addr) = reg_val(virt_addr) | mask;
00178 }
00179
00180 static void bit_clear_clk(unsigned long addr,unsigned gpio)
00181 {
00182 void * virt_addr;
00183 unsigned long mask;
00184
00185 virt_addr = map_base_clk + ((addr+(gpio/32)*4) & MAP_MASK);
00186 mask = 1 << (gpio%32);
00187
00188 reg_val(virt_addr) = reg_val(virt_addr) & ~mask;
00189 }
00190
00199 int kb_clk_init()
00200 {
00201
00202
00203 if((fd_clk = open(MEMDEV, O_RDWR | O_SYNC)) == -1)
00204 {
00205 KB_ERROR("kb_clk_init",KB_ERROR_FILEOPEN,MEMDEV);
00206 return -KB_ERROR_FILEOPEN;
00207 }
00208
00209
00210 map_base_clk = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd_clk, CLK_BASE & ~MAP_MASK);
00211 if(map_base_clk == (void *) -1)
00212 {
00213 KB_ERROR("kb_clk_init",KB_ERROR_MMAP,CLK_BASE & ~MAP_MASK);
00214 return -KB_ERROR_MMAP;
00215 }
00216
00217 return 0;
00218 }
00219
00220
00221
00230 int kb_pwm0_init()
00231 {
00232
00233
00234 if((fd_pwm0 = open(MEMDEV, O_RDWR | O_SYNC)) == -1)
00235 {
00236 KB_ERROR("kb_pwm0_init",KB_ERROR_FILEOPEN,MEMDEV);
00237 return -KB_ERROR_FILEOPEN;
00238 }
00239
00240
00241 map_base_pwm0 = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd_pwm0, PWM0_BASE & ~MAP_MASK);
00242 if(map_base_pwm0 == (void *) -1)
00243 {
00244 KB_ERROR("kb_pwm0_init",KB_ERROR_MMAP,PWM0_BASE & ~MAP_MASK);
00245 return -KB_ERROR_MMAP;
00246 }
00247
00248 return 0;
00249 }
00258 int kb_pwm1_init()
00259 {
00260
00261
00262
00263
00264 if((fd_pwm1 = open(MEMDEV, O_RDWR | O_SYNC)) == -1)
00265 {
00266 KB_ERROR("kb_pwm1_init",KB_ERROR_FILEOPEN,MEMDEV);
00267 return -KB_ERROR_FILEOPEN;
00268 }
00269
00270
00271 map_base_pwm1 = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd_pwm1, PWM1_BASE & ~MAP_MASK);
00272 if(map_base_pwm1 == (void *) -1)
00273 {
00274 KB_ERROR("kb_pwm1_init",KB_ERROR_MMAP,PWM1_BASE & ~MAP_MASK);
00275 return -KB_ERROR_MMAP;
00276 }
00277
00278 return 0;
00279 }
00280
00289 int kb_pwm_init()
00290 {
00291 kb_pwm0_init();
00292 kb_pwm1_init();
00293
00294 kb_clk_init();
00295 kb_gpio_init();
00296 }
00297
00301 int kb_pwm_cleanup()
00302 {
00303 if(munmap(map_base_pwm0, MAP_SIZE) == -1) KB_ERROR("kb_pwm0_cleanup",KB_ERROR_MMAP,map_base_pwm0);
00304 close(fd_pwm0);
00305 if(munmap(map_base_pwm1, MAP_SIZE) == -1) KB_ERROR("kb_pwm1_cleanup",KB_ERROR_MMAP,map_base_pwm1);
00306 close(fd_pwm1);
00307 }
00308
00309
00317 int kb_pwm_activate(unsigned pwm)
00318 {
00319
00320
00321 if(pwm >= MAXPWM)
00322 {
00323 KB_ERROR("kb_pwm_activate",KB_ERROR_INVALID);
00324 return -KB_ERROR_INVALID;
00325 }
00326
00327
00328
00329
00330 if (pwm)
00331 {
00332
00333 kb_gpio_dir(PWM1,0);
00334
00335 kb_gpio_function(PWM1,2);
00336
00337 }
00338
00339 else
00340 {
00341
00342
00343 kb_gpio_dir(PWM0,0);
00344
00345 kb_gpio_function(PWM0,2);
00346
00347 }
00348
00349 bit_set_clk(CKEN,pwm);
00350
00351
00352
00353
00354 return 0;
00355 }
00356
00363 int kb_pwm_desactivate(unsigned pwm)
00364 {
00365 if(pwm >= MAXPWM)
00366 {
00367 KB_ERROR("kb_pwm_desactivate",KB_ERROR_INVALID);
00368 return -KB_ERROR_INVALID;
00369 }
00370
00371
00372 bit_clear_clk(CKEN,pwm);
00373
00374 return 0;
00375 }
00376
00377
00378
00379
00390 int kb_pwm_config(unsigned pwm, unsigned pwm_sd, unsigned prescale)
00391 {
00392 unsigned long tmp;
00393
00394 if(pwm >= MAXPWM)
00395 {
00396 KB_ERROR("kb_pwm_config",KB_ERROR_INVALID);
00397 return -KB_ERROR_INVALID;
00398 }
00399
00400
00401
00402
00403
00404 if(pwm_sd)
00405 tmp = (prescale & 0x003F) | 0x0040;
00406 else
00407 tmp = (prescale & 0x003F);
00408
00409
00410
00411
00412 if (pwm)
00413 reg_set_pwm1(PWM_CTRL1,tmp);
00414
00415 else
00416 reg_set_pwm0(PWM_CTRL0,tmp);
00417
00418 return 0;
00419 }
00420
00421
00429 int kb_pwm_duty(unsigned pwm, unsigned FDcycle, unsigned Dcycle)
00430 {
00431 unsigned long tmp;
00432
00433 if(pwm >= MAXPWM)
00434 {
00435 KB_ERROR("kb_pwm_duty",KB_ERROR_INVALID);
00436 return -KB_ERROR_INVALID;
00437 }
00438
00439
00440 if(FDcycle)
00441 tmp = (Dcycle & 0x03FF) | 0x0400;
00442 else
00443 tmp = (Dcycle & 0x03FF);
00444
00445
00446 if (pwm)
00447 reg_set_pwm1(PWM_PWDUTY1,tmp);
00448
00449 else
00450 reg_set_pwm0(PWM_PWDUTY0,tmp);
00451
00452
00453
00454
00455
00456 return 0;
00457
00458
00459 }
00460
00461
00468 int kb_pwm_period(unsigned pwm, unsigned pwm_period)
00469 {
00470
00471 if(pwm >= MAXPWM)
00472 {
00473 KB_ERROR("kb_pwm_period",KB_ERROR_INVALID);
00474 return -KB_ERROR_INVALID;
00475 }
00476
00477
00478 if (pwm)
00479 reg_set_pwm1(PWM_PERVAL1,pwm_period);
00480
00481 else
00482 reg_set_pwm0(PWM_PERVAL0,pwm_period);
00483
00484 return 0;
00485 }