From a660948600becfa725ea5807d5ba3e075f2a1065 Mon Sep 17 00:00:00 2001 From: Richard Hirst Date: Sun, 2 Dec 2012 10:03:29 +0000 Subject: [PATCH] Fix PWM initialisation --- ServoBlaster/servoblaster.c | 23 ++++++++++++++++++----- ServoBlaster/servoblaster.ko | Bin 10755 -> 10863 bytes 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ServoBlaster/servoblaster.c b/ServoBlaster/servoblaster.c index bf3ce35..03af80a 100644 --- a/ServoBlaster/servoblaster.c +++ b/ServoBlaster/servoblaster.c @@ -65,6 +65,7 @@ #define GPCLR0 (0x28/4) #define PWM_CTL (0x00/4) +#define PWM_STA (0x04/4) #define PWM_DMAC (0x08/4) #define PWM_RNG1 (0x10/4) #define PWM_FIFO (0x18/4) @@ -283,14 +284,25 @@ int init_module(void) // Point last cb back to first one so it loops continuously ctl->cb[NUM_SERVOS*4-1].next = (uint32_t)(ctl->cb) & 0x7fffffff; - // Initialise PWM + // Initialise PWM - these delays may not all be necessary, but at least + // I seem to be able to switch between PWM audio and servoblaster + // reliably with this code. pwm_reg[PWM_CTL] = 0; udelay(10); - clk_reg[PWMCLK_DIV] = 0x5A000000 | (32<<12); // set pwm div to 32 (19.2MHz/32 = 600KHz) - clk_reg[PWMCLK_CNTL] = 0x5A000011; // Source=osc and enable - pwm_reg[PWM_RNG1] = tick_scale; // 600KHz/6 = 10us per FIFO write + pwm_reg[PWM_STA] = pwm_reg[PWM_STA]; udelay(10); - ctl->pwmdata = 1; // Give a pulse of one clock width for each fifo write + clk_reg[PWMCLK_CNTL] = 0x5A000000; + clk_reg[PWMCLK_DIV] = 0x5A000000; + clk_reg[PWMCLK_CNTL] = 0x5A000001; // Source=osc + clk_reg[PWMCLK_DIV] = 0x5A000000 | (32<<12); // set pwm div to 32 (19.2MHz/32 = 600KHz) + udelay(500); // Delay needed before enabling + clk_reg[PWMCLK_CNTL] = 0x5A000011; // Source=osc and enable + + udelay(500); + + pwm_reg[PWM_RNG1] = tick_scale; // 600KHz/6 = 10us per FIFO write + udelay(10); + ctl->pwmdata = 1; // Give a pulse of one clock width for each fifo write pwm_reg[PWM_DMAC] = PWMDMAC_ENAB | PWMDMAC_THRSHLD; udelay(10); pwm_reg[PWM_CTL] = PWMCTL_CLRF; @@ -304,6 +316,7 @@ int init_module(void) dma_reg[DMA_CS] = BCM2708_DMA_INT | BCM2708_DMA_END; dma_reg[DMA_CONBLK_AD] = (uint32_t)(ctl->cb) & 0x7fffffff; dma_reg[DMA_DEBUG] = 7; // clear debug error flags + udelay(10); dma_reg[DMA_CS] = 0x10880001; // go, mid priority, wait for outstanding writes return 0; diff --git a/ServoBlaster/servoblaster.ko b/ServoBlaster/servoblaster.ko index 582a1c9550888c541dce01c9b25b7652af9f814d..25e6706e4676771a8dd50dcf907f743470b90325 100644 GIT binary patch delta 1216 zcmZXTUue@;6vxj^lQeDPNclz6{OSC~wx-1@zov<1&^_38B2uwP2I4vzP2-HqnrNa_ zDYmp_sB4()^udRP{16}dV5OQ0MdpLxU=KcQFt$Eyj5fQ>KS9kNwt{TkxxZf6V1fJl zobx?j&OP`3ewmKGie6XQ`dxpYrK738$bH`)UTcS$HKyuid#K3&-q?5nFj#g%o>u`L zv}<#G9rKp$>?d5Xw6GuXJBq)=szurIJwW}ELoYkk0-wZ2tJ0jw7I_9{c&cWz)4Z$# zX+yZ*s(1!u<)BjJW2Bm4&e*d@!BOi`R>4Qs0Q&}?SwC`*OcnXa%_6r=PIFbC=C;KG zH|qr+#bmA5s@*Gc?IvEU-D5IO;e*=Ii5qNl(=i%(mSVGtw5E;rIns`|>g6%gb<%Fp zV(QeIh)?^AMlOynd_$BEN}tfol#8Ab(o*Ud+#!3K)j7`SfTE^4r>wl4j7~gjQ#ydG zAZ?=Tr`xT-zZ#Hc^6TXlT(IqGyG<42-br0jH(gFB(7Va6z5e{+Q*h|3I#zA2Ewj@3 z`^Lue8QfZzZdeI+*8rG~Hv-^ibsa2^_v?OR%cVm7Ddy^n1U0R@Hx%rBFB0B&U~gn! zBzT~=yX3L&X>j&_aPr8X7g{_2*fn^lW98bL$9MK$z{{>3rOU1}jAigyQ;TKU2QY?> z?iS0fdH_4#bt^dFcCbbK&>b*o+woKPPWBoX+yRTD0pJE!JqlLHFpqzcA@vsCac{#O zkAq#o!=3<}#q;!hf(3dmmsb?F$^z39$ajQ4LX7F8az%uUw7&o>W_liz=(ki3@ zu6h-GLRtlXCe76Z@Qb1Od=9pbyM6TKl-~EH*@WE&;EMx}2pqc&_lDDP4D7hrL zPV}7tXrk*E2Wk~O2GA)Or2|U#NcJ1_0t|?NCL1C))8sKCO$Mpb!?%?hzZi7$$G}0s z@_+JX%44Of|CNc}(Q0cSyIyK*`+-e_yMi!0{7HIbIG2onJe-Z6NF{O?Gl_6lm(=4I zibeJ0+b{JfJxbKx8&b?wyP^1|f20efIdPAr zqS7QCs4(~_sV2x2W`5p`LzaVV3TG`omck{=F}FHF@%}crHI?RCHqEWmliZY@1aNK!C{@|A?@Wl4FVYpS3KGL0xns%vuX5{ zy6XO-4dOig^o?SO=)bJ3y*n@UPt>Qdw=`Z-4sZxS!KbASEQ`$cmg%`A+fn9f4Yjs( z?A_ZL4F1*>YHABK2Usi=6|MlK#=g6i*k^FoMgv;i}uK%-OJ}vYz$e@0C8L;VG&r z{zrcj?#rSPh#4XRJM@4|y>J-dWs zB=zL3t8q5&wF0OSfKJJ7NnJ7}d0X%>z=GfrfM;_3TJnRS4zMbHYbhO{9l$PV0dNS? z?G)S(u(haL9Slk_wh8~MVhZ6L7vlRMICy&QRg5e!< XJrGSqMq