Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Adding low level buffer operations ro RPIO.PWM #20

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

PaulPenson
Copy link

This change adds functionality that allows the assignment of individual GPIO channel commands to the DMA ring buffer. This allows pulses length to be changed with minimal cost.

Below is an example python usage, it demonstrates a single dma channel being used to control 9 channels of PWM output [three banks of RGB leds]. The LED color can be faded with no flickers or glitches, and there is a minimal cost to change the pulse width. The on and off commands are pre-setup to allow each of the channels to start at a different phase of the cycle to reduce the current surge.

The on instructions are at fixed positions so that we do no attempt to reassign them to off instructions.

from RPIO import PWM

class LightController:
dmachannel = 0
channels = [24,23,25,15,18,14,9,11,10]
starts = [0,333,666,999,1332,1665,1998,2331,2664]
lastPos = [0,333,666,999,1332,1665,1998,2331,2664]

    def __init__(self):
        PWM.set_loglevel(PWM.LOG_LEVEL_ERRORS)
        PWM.setup(1,PWM.DELAY_VIA_PCM)
        PWM.init_channel(self.dmachannel,3000)
        for x in range(self.dmachannel, 2999):
            PWM.buffer_set_off(self.dmachannel,x)
        for p in self.starts:
            PWM.buffer_set_on(self.dmachannel,p)
        self.setcolor(0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1)
        self.setcolor(0,0,0,0,0,0,0,0,0)

    def setchannel( self, index, brightness ):
        start = self.starts[index]
        channel = self.channels[index]
        last = self.lastPos[index]
        end = start + int((brightness**2)*2999)
        if end>=3000:
            end -= 3000
        if end!=start:
            for p in self.starts:
                if end==p:
                    end = end+1
            if end!=last:
                PWM.buffer_assign(self.dmachannel,channel,end)
                if last==start:
                    PWM.buffer_assign(self.dmachannel,channel,start)
                else:
                    PWM.buffer_unassign(self.dmachannel,channel,last)
        else:
            if last!=start:
                PWM.buffer_unassign(self.dmachannel,channel,start)
                PWM.buffer_unassign(self.dmachannel,channel,last)
        self.lastPos[index]=end

    def setcolor( self, r1, g1, b1, r2, g2, b2, r3, g3, b3 ):
        self.setchannel(0,r1)
        self.setchannel(1,g1)
        self.setchannel(2,b1)
        self.setchannel(3,r2)
        self.setchannel(4,g2)
        self.setchannel(5,b2)
        self.setchannel(6,r3)
        self.setchannel(7,g3)
        self.setchannel(8,b3)

Chris Hager and others added 6 commits April 7, 2013 07:01
Mention the Arch Linux PKGBUILD in README.rst. Thank you very much nils-werner!
Added low level buffer operations
@metachris
Copy link
Owner

Thanks, I hope I'll find the time to review. Could you update the PR with the latest source? I've merged a few PRs in the meantime!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants