Actual code

master
Skylten 4 years ago
parent 6ad76786b7
commit 205ccbce1d

@ -0,0 +1,9 @@
package: libws2811
Version: 1.1.0-1
Section: base
Priority: optional
Architecture: armhf
Depends:
Maintainer: Jeremy Garff (jer@jers.net)
Description: Raspberry Pi WS281X Library
LED Control Library for the Raspberry Pi.

@ -0,0 +1,45 @@
#!/bin/sh
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
# source debconf library
. /usr/share/debconf/confmodule
# Source dbconfig-common functions
if [ -f /usr/share/dbconfig-common/dpkg/postinst.pgsql ]; then
. /usr/share/dbconfig-common/dpkg/postinst.pgsql
fi
case "$1" in
configure)
ldconfig
;;
abort-upgrade|abort-remove|abort-deconfigure)
exit 0
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
db_stop
exit 0
~

@ -0,0 +1,45 @@
#!/bin/sh
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
# source debconf library
. /usr/share/debconf/confmodule
# Source dbconfig-common functions
if [ -f /usr/share/dbconfig-common/dpkg/postinst.pgsql ]; then
. /usr/share/dbconfig-common/dpkg/postinst.pgsql
fi
case "$1" in
remove)
ldconfig
;;
abort-upgrade|abort-remove|abort-deconfigure)
exit 0
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
;;
esac
db_stop
exit 0
~

@ -0,0 +1,44 @@
#!/bin/sh
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
# source debconf library
. /usr/share/debconf/confmodule
# Source dbconfig-common functions
if [ -f /usr/share/dbconfig-common/dpkg/postinst.pgsql ]; then
. /usr/share/dbconfig-common/dpkg/postinst.pgsql
fi
case "$1" in
remove|upgrade|deconfigure)
;;
abort-upgrade|abort-remove|abort-deconfigure)
exit 0
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
db_stop
exit 0

@ -0,0 +1,24 @@
Copyright (c) 2014, jgarff
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -0,0 +1,95 @@
#
# SConscript
#
# Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted
# provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
# 3. Neither the name of the owner nor the names of its contributors may be used to endorse
# or promote products derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
Import(['clean_envs'])
tools_env = clean_envs['userspace'].Clone()
# Build Library
lib_srcs = Split('''
mailbox.c
ws2811.c
pwm.c
pcm.c
dma.c
rpihw.c
''')
version_hdr = tools_env.Version('version')
ws2811_lib = tools_env.Library('libws2811', lib_srcs)
tools_env['LIBS'].append(ws2811_lib)
# Shared library (if required)
ws2811_slib = tools_env.SharedLibrary('libws2811', lib_srcs)
# Test Program
srcs = Split('''
main.c
''')
objs = []
for src in srcs:
objs.append(tools_env.Object(src))
test = tools_env.Program('test', objs + tools_env['LIBS'])
Default([test, ws2811_lib])
package_version = "1.1.0-1"
package_name = 'libws2811_%s' % package_version
debian_files = [
'DEBIAN/control',
'DEBIAN/postinst',
'DEBIAN/prerm',
'DEBIAN/postrm',
]
package_files_desc = [
[ '/usr/lib', ws2811_slib ],
]
package_files = []
for target in package_files_desc:
package_files.append(tools_env.Install(package_name + target[0], target[1]))
for deb_file in debian_files:
package_files.append(
tools_env.Command('%s/%s' % (package_name, deb_file), deb_file, [
Copy("$TARGET", "$SOURCE"),
Chmod("$TARGET", 0755)
])
)
package = tools_env.Command('%s.deb' % package_name, package_files,
'cd %s; dpkg-deb --build %s' % (Dir('.').abspath, package_name));
Alias("deb", package)

@ -0,0 +1,76 @@
#
# SConstruct
#
# Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted
# provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
# 3. Neither the name of the owner nor the names of its contributors may be used to endorse
# or promote products derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
import os
opts = Variables()
opts.Add(BoolVariable('V',
'Verbose build',
False))
opts.Add('TOOLCHAIN',
'Set toolchain for cross compilation (e.g. arm-linux-gnueabihf)',
'')
platforms = [
[
'userspace', # Target Name
[ 'linux', 'version' ], # Scons tool (linux, avr, etc.)
{ # Special environment setup
'CPPPATH' : [
],
'LINKFLAGS' : [
"-lrt",
],
},
],
]
clean_envs = {}
for platform, tool, flags in platforms:
env = Environment(
options = opts,
tools = tool,
toolpath = ['.'],
ENV = {'PATH' : os.environ['PATH']},
LIBS = [],
)
env.MergeFlags(flags)
clean_envs[platform] = env
Help(opts.GenerateHelpText(clean_envs))
if env['TOOLCHAIN'] != '':
env['CC'] = env['TOOLCHAIN'] + '-gcc'
env['AR'] = env['TOOLCHAIN'] + '-ar'
Export(['clean_envs'])
SConscript('SConscript');

65
clk.h

@ -0,0 +1,65 @@
/*
* clk.h
*
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __CLK_H__
#define __CLK_H__
typedef struct {
uint32_t ctl;
#define CM_CLK_CTL_PASSWD (0x5a << 24)
#define CM_CLK_CTL_MASH(val) ((val & 0x3) << 9)
#define CM_CLK_CTL_FLIP (1 << 8)
#define CM_CLK_CTL_BUSY (1 << 7)
#define CM_CLK_CTL_KILL (1 << 5)
#define CM_CLK_CTL_ENAB (1 << 4)
#define CM_CLK_CTL_SRC_GND (0 << 0)
#define CM_CLK_CTL_SRC_OSC (1 << 0)
#define CM_CLK_CTL_SRC_TSTDBG0 (2 << 0)
#define CM_CLK_CTL_SRC_TSTDBG1 (3 << 0)
#define CM_CLK_CTL_SRC_PLLA (4 << 0)
#define CM_CLK_CTL_SRC_PLLC (5 << 0)
#define CM_CLK_CTL_SRC_PLLD (6 << 0)
#define CM_CLK_CTL_SRC_HDMIAUX (7 << 0)
uint32_t div;
#define CM_CLK_DIV_PASSWD (0x5a << 24)
#define CM_CLK_DIV_DIVI(val) ((val & 0xfff) << 12)
#define CM_CLK_DIV_DIVF(val) ((val & 0xfff) << 0)
} __attribute__((packed, aligned(4))) cm_clk_t;
/*
* PWM and PCM clock offsets from https://www.scribd.com/doc/127599939/BCM2835-Audio-clocks
*
*/
#define CM_PCM_OFFSET (0x00101098)
#define CM_PWM_OFFSET (0x001010a0)
#endif /* __CLK_H__ */

78
dma.c

@ -0,0 +1,78 @@
/*
* dma.c
*
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "dma.h"
// DMA address mapping by DMA number index
static const uint32_t dma_offset[] =
{
DMA0_OFFSET,
DMA1_OFFSET,
DMA2_OFFSET,
DMA3_OFFSET,
DMA4_OFFSET,
DMA5_OFFSET,
DMA6_OFFSET,
DMA7_OFFSET,
DMA8_OFFSET,
DMA9_OFFSET,
DMA10_OFFSET,
DMA11_OFFSET,
DMA12_OFFSET,
DMA13_OFFSET,
DMA14_OFFSET,
DMA15_OFFSET,
};
uint32_t dmanum_to_offset(int dmanum)
{
int array_size = sizeof(dma_offset) / sizeof(dma_offset[0]);
if (dmanum >= array_size)
{
return 0;
}
return dma_offset[dmanum];
}

126
dma.h

@ -0,0 +1,126 @@
/*
* dma.h
*
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __DMA_H__
#define __DMA_H__
/*
* DMA Control Block in Main Memory
*
* Note: Must start at a 256 byte aligned address.
* Use corresponding register field definitions.
*/
typedef struct
{
uint32_t ti;
uint32_t source_ad;
uint32_t dest_ad;
uint32_t txfr_len;
uint32_t stride;
uint32_t nextconbk;
uint32_t resvd_0x18[2];
} __attribute__((packed, aligned(4))) dma_cb_t;
/*
* DMA register set
*/
typedef struct
{
uint32_t cs;
#define RPI_DMA_CS_RESET (1 << 31)
#define RPI_DMA_CS_ABORT (1 << 30)
#define RPI_DMA_CS_DISDEBUG (1 << 29)
#define RPI_DMA_CS_WAIT_OUTSTANDING_WRITES (1 << 28)
#define RPI_DMA_CS_PANIC_PRIORITY(val) ((val & 0xf) << 20)
#define RPI_DMA_CS_PRIORITY(val) ((val & 0xf) << 16)
#define RPI_DMA_CS_ERROR (1 << 8)
#define RPI_DMA_CS_WAITING_OUTSTANDING_WRITES (1 << 6)
#define RPI_DMA_CS_DREQ_STOPS_DMA (1 << 5)
#define RPI_DMA_CS_PAUSED (1 << 4)
#define RPI_DMA_CS_DREQ (1 << 3)
#define RPI_DMA_CS_INT (1 << 2)
#define RPI_DMA_CS_END (1 << 1)
#define RPI_DMA_CS_ACTIVE (1 << 0)
uint32_t conblk_ad;
uint32_t ti;
#define RPI_DMA_TI_NO_WIDE_BURSTS (1 << 26)
#define RPI_DMA_TI_WAITS(val) ((val & 0x1f) << 21)
#define RPI_DMA_TI_PERMAP(val) ((val & 0x1f) << 16)
#define RPI_DMA_TI_BURST_LENGTH(val) ((val & 0xf) << 12)
#define RPI_DMA_TI_SRC_IGNORE (1 << 11)
#define RPI_DMA_TI_SRC_DREQ (1 << 10)
#define RPI_DMA_TI_SRC_WIDTH (1 << 9)
#define RPI_DMA_TI_SRC_INC (1 << 8)
#define RPI_DMA_TI_DEST_IGNORE (1 << 7)
#define RPI_DMA_TI_DEST_DREQ (1 << 6)
#define RPI_DMA_TI_DEST_WIDTH (1 << 5)
#define RPI_DMA_TI_DEST_INC (1 << 4)
#define RPI_DMA_TI_WAIT_RESP (1 << 3)
#define RPI_DMA_TI_TDMODE (1 << 1)
#define RPI_DMA_TI_INTEN (1 << 0)
uint32_t source_ad;
uint32_t dest_ad;
uint32_t txfr_len;
#define RPI_DMA_TXFR_LEN_YLENGTH(val) ((val & 0xffff) << 16)
#define RPI_DMA_TXFR_LEN_XLENGTH(val) ((val & 0xffff) << 0)
uint32_t stride;
#define RPI_DMA_STRIDE_D_STRIDE(val) ((val & 0xffff) << 16)
#define RPI_DMA_STRIDE_S_STRIDE(val) ((val & 0xffff) << 0)
uint32_t nextconbk;
uint32_t debug;
} __attribute__((packed, aligned(4))) dma_t;
#define DMA0_OFFSET (0x00007000)
#define DMA1_OFFSET (0x00007100)
#define DMA2_OFFSET (0x00007200)
#define DMA3_OFFSET (0x00007300)
#define DMA4_OFFSET (0x00007400)
#define DMA5_OFFSET (0x00007500)
#define DMA6_OFFSET (0x00007600)
#define DMA7_OFFSET (0x00007700)
#define DMA8_OFFSET (0x00007800)
#define DMA9_OFFSET (0x00007900)
#define DMA10_OFFSET (0x00007a00)
#define DMA11_OFFSET (0x00007b00)
#define DMA12_OFFSET (0x00007c00)
#define DMA13_OFFSET (0x00007d00)
#define DMA14_OFFSET (0x00007e00)
#define DMA15_OFFSET (0x00e05000)
#define PAGE_SIZE (1 << 12)
#define PAGE_MASK (~(PAGE_SIZE - 1))
#define PAGE_OFFSET(page) (page & (PAGE_SIZE - 1))
uint32_t dmanum_to_offset(int dmanum);
#endif /* __DMA_H__ */

@ -0,0 +1,28 @@
## Deprecated
This Go code is being phased out and replaced with https://github.com/rpi-ws281x/rpi-ws281x-go
For issues and bugs with (or contributions to) the Go library, please see: https://github.com/rpi-ws281x/rpi-ws281x-go/issues
----
## Run a demo
As this is just a Go wrapper for the library you must clone this into your `$GOPATH` as you would any other Go program.
Your path to the project should be:
```
$GOPATH/src/github.com/jgraff/rpi_ws281x
```
As listed in the `ws2811.go` file ensure to copy `ws2811.h`, `rpihw.h`, and `pwm.h` in a GCC include path (e.g. `/usr/local/include`) and
`libws2811.a` in a GCC library path (e.g. `/usr/local/lib`).
To run the basic example run the following commands:
```
cd golang/examples
go build basic.go
sudo ./basic
```
If everything worked you should see a basic color wipe for the first 16 LEDs on your strip.

@ -0,0 +1,60 @@
package main
import (
"time"
"os"
"fmt"
"github.com/jgarff/rpi_ws281x/golang/ws2811"
)
const (
pin = 18
count = 16
brightness = 255
)
func main() {
defer ws2811.Fini()
err := ws2811.Init(pin, count, brightness)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Press Ctr-C to quit.")
fmt.Println("Creating blue color wipe")
err = colorWipe(uint32(0x000020))
if err != nil {
fmt.Println("Error during wipe " + err.Error())
os.Exit(-1)
}
fmt.Println("Creating red color wipe")
err = colorWipe(uint32(0x002000))
if err != nil {
fmt.Println("Error during wipe " + err.Error())
os.Exit(-1)
}
fmt.Println("Creating green color wipe")
err = colorWipe(uint32(0x200000))
if err != nil {
fmt.Println("Error during wipe " + err.Error())
os.Exit(-1)
}
}
}
func colorWipe(color uint32) error {
for i := 0; i < count; i++ {
ws2811.SetLed(i, color)
err := ws2811.Render()
if err != nil {
ws2811.Clear()
return err
}
time.Sleep(50 * time.Millisecond)
}
return nil
}

@ -0,0 +1,91 @@
// Copyright (c) 2015, Jacques Supcik, HEIA-FR
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the <organization> nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*
Interface to ws2811 chip (neopixel driver). Make sure that you have
ws2811.h, rpihw.h, and pwm.h in a GCC include path (e.g. /usr/local/include) and
libws2811.a in a GCC library path (e.g. /usr/local/lib).
See https://github.com/jgarff/rpi_ws281x for instructions
*/
package ws2811
/*
#cgo CFLAGS: -std=c99
#cgo LDFLAGS: -lws2811
#include "ws2811.go.h"
*/
import "C"
import (
"errors"
"fmt"
"unsafe"
)
func Init(gpioPin int, ledCount int, brightness int) error {
C.ledstring.channel[0].gpionum = C.int(gpioPin)
C.ledstring.channel[0].count = C.int(ledCount)
C.ledstring.channel[0].brightness = C.uint8_t(brightness)
res := int(C.ws2811_init(&C.ledstring))
if res == 0 {
return nil
} else {
return errors.New(fmt.Sprintf("Error ws2811.init.%d", res))
}
}
func Fini() {
C.ws2811_fini(&C.ledstring)
}
func Render() error {
res := int(C.ws2811_render(&C.ledstring))
if res == 0 {
return nil
} else {
return errors.New(fmt.Sprintf("Error ws2811.render.%d", res))
}
}
func Wait() error {
res := int(C.ws2811_wait(&C.ledstring))
if res == 0 {
return nil
} else {
return errors.New(fmt.Sprintf("Error ws2811.wait.%d", res))
}
}
func SetLed(index int, value uint32) {
C.ws2811_set_led(&C.ledstring, C.int(index), C.uint32_t(value))
}
func Clear() {
C.ws2811_clear(&C.ledstring)
}
func SetBitmap(a []uint32) {
C.ws2811_set_bitmap(&C.ledstring, unsafe.Pointer(&a[0]), C.int(len(a)*4))
}

@ -0,0 +1,64 @@
/***********************************************************************************
* Copyright (c) 2015, Jacques Supcik, HEIA-FR
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************************/
#include <stdint.h>
#include <string.h>
#include <ws2811.h>
ws2811_t ledstring = {
.freq = 800000,
.dmanum = 10,
.channel = {
[0] = {
.gpionum = 18,
.count = 256,
.invert = 0,
.brightness = 32,
},
[1] = {
.gpionum = 0,
.count = 0,
.invert = 0,
.brightness = 0,
},
},
};
void ws2811_set_led(ws2811_t *ws2811, int index, uint32_t value) {
ws2811->channel[0].leds[index] = value;
}
void ws2811_clear(ws2811_t *ws2811) {
for (int chan = 0; chan < RPI_PWM_CHANNELS; chan++) {
ws2811_channel_t *channel = &ws2811->channel[chan];
memset(channel->leds, 0, sizeof(ws2811_led_t) * channel->count);
}
}
void ws2811_set_bitmap(ws2811_t *ws2811, void* a, int len) {
memcpy(ws2811->channel[0].leds, a, len);
}

108
gpio.h

@ -0,0 +1,108 @@
/*
* gpio.h
*
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __GPIO_H__
#define __GPIO_H__
typedef struct
{
uint32_t fsel[6]; // GPIO Function Select
uint32_t resvd_0x18;
uint32_t set[2]; // GPIO Pin Output Set
uint32_t resvd_0x24;
uint32_t clr[2]; // GPIO Pin Output Clear
uint32_t resvd_0x30;
uint32_t lev[2]; // GPIO Pin Level
uint32_t resvd_0x3c;
uint32_t eds[2]; // GPIO Pin Event Detect Status
uint32_t resvd_0x48;
uint32_t ren[2]; // GPIO Pin Rising Edge Detect Enable
uint32_t resvd_0x54;
uint32_t fen[2]; // GPIO Pin Falling Edge Detect Enable
uint32_t resvd_0x60;
uint32_t hen[2]; // GPIO Pin High Detect Enable
uint32_t resvd_0x6c;
uint32_t len[2]; // GPIO Pin Low Detect Enable
uint32_t resvd_0x78;
uint32_t aren[2]; // GPIO Pin Async Rising Edge Detect
uint32_t resvd_0x84;
uint32_t afen[2]; // GPIO Pin Async Falling Edge Detect
uint32_t resvd_0x90;
uint32_t pud; // GPIO Pin Pull up/down Enable
uint32_t pudclk[2]; // GPIO Pin Pull up/down Enable Clock
uint32_t resvd_0xa0[4];
uint32_t test;
} __attribute__((packed, aligned(4))) gpio_t;
#define GPIO_OFFSET (0x00200000)
static inline void gpio_function_set(volatile gpio_t *gpio, uint8_t pin, uint8_t function)
{
int regnum = pin / 10;
int offset = (pin % 10) * 3;
uint8_t funcmap[] = { 4, 5, 6, 7, 3, 2 }; // See datasheet for mapping
if (function > 5)
{
return;
}
gpio->fsel[regnum] &= ~(0x7 << offset);
gpio->fsel[regnum] |= ((funcmap[function]) << offset);
}
static inline void gpio_level_set(volatile gpio_t *gpio, uint8_t pin, uint8_t level)
{
int regnum = pin >> 5;
int offset = (pin & 0x1f);
if (level)
{
gpio->set[regnum] = (1 << offset);
}
else
{
gpio->clr[regnum] = (1 << offset);
}
}
static inline void gpio_output_set(volatile gpio_t *gpio, uint8_t pin, uint8_t output)
{
int regnum = pin / 10;
int offset = (pin % 10) * 3;
uint8_t function = output ? 1 : 0; // See datasheet for mapping
gpio->fsel[regnum] &= ~(0x7 << offset);
gpio->fsel[regnum] |= ((function & 0x7) << offset);
}
#endif /* __GPIO_H__ */

@ -0,0 +1,84 @@
#
# linux.py
#
# Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted
# provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
# 3. Neither the name of the owner nor the names of its contributors may be used to endorse
# or promote products derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
import SCons
import string
import array
import os
tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas']
def linux_tools(env):
for tool in tools:
env.Tool(tool)
if not env['V']:
env['ARCOMSTR'] = 'AR ${TARGET}'
env['ASCOMSTR'] = 'AS ${TARGET}'
env['CCCOMSTR'] = 'CC ${TARGET}'
env['CXXCOMSTR'] = 'C++ ${TARGET}'
env['LINKCOMSTR'] = 'LINK ${TARGET}'
env['RANLIBCOMSTR'] = 'RANLIB ${TARGET}'
def linux_flags(env):
env.MergeFlags({
'CPPFLAGS' : '''
-fPIC
-g
-O2
-Wall
-Wextra
-Werror
'''.split(),
}),
env.MergeFlags({
'LINKFLAGS' : '''
'''.split()
})
def linux_builders(env):
env.Append(BUILDERS = {
'Program' : SCons.Builder.Builder(
action = SCons.Action.Action('${LINK} -o ${TARGET} ${SOURCES} ${LINKFLAGS}',
'${LINKCOMSTR}'),
),
})
return 1
# The following are required functions by SCons when incorporating through tools
def exists(env):
return 1
def generate(env, **kwargs):
[f(env) for f in (linux_tools, linux_flags, linux_builders)]

@ -0,0 +1,292 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd.
Copyright (c) 2016, Jeremy Garff
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include "mailbox.h"
void *mapmem(uint32_t base, uint32_t size, const char *mem_dev) {
uint32_t pagemask = ~0UL ^ (getpagesize() - 1);
uint32_t offsetmask = getpagesize() - 1;
int mem_fd;
void *mem;
mem_fd = open(mem_dev, O_RDWR | O_SYNC);
if (mem_fd < 0) {
perror("Can't open /dev/mem");
return NULL;
}
mem = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, base & pagemask);
if (mem == MAP_FAILED) {
perror("mmap error\n");
return NULL;
}
close(mem_fd);
return (char *)mem + (base & offsetmask);
}
void *unmapmem(void *addr, uint32_t size) {
uint32_t pagemask = ~0UL ^ (getpagesize() - 1);
uintptr_t baseaddr = (uintptr_t)addr & pagemask;
int s;
s = munmap((void *)baseaddr, size);
if (s != 0) {
perror("munmap error\n");
}
return NULL;
}
/*
* use ioctl to send mbox property message
*/
static int mbox_property(int file_desc, void *buf) {
int fd = file_desc;
int ret_val = -1;
if (fd < 0) {
fd = mbox_open();
}
if (fd >= 0) {
ret_val = ioctl(fd, IOCTL_MBOX_PROPERTY, buf);
if (ret_val < 0) {
perror("ioctl_set_msg failed\n");
}
}
if (file_desc < 0) {
mbox_close(fd);
}
return ret_val;
}
uint32_t mem_alloc(int file_desc, uint32_t size, uint32_t align, uint32_t flags) {
int i=0;
uint32_t p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x3000c; // (the tag id)
p[i++] = 12; // (size of the buffer)
p[i++] = 12; // (size of the data)
p[i++] = size; // (num bytes? or pages?)
p[i++] = align; // (alignment)
p[i++] = flags; // (MEM_FLAG_L1_NONALLOCATING)
p[i++] = 0x00000000; // end tag
p[0] = i*sizeof *p; // actual size
if (mbox_property(file_desc, p) < 0)
return 0;
else
return p[5];
}
uint32_t mem_free(int file_desc, uint32_t handle) {
int i=0;
uint32_t p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x3000f; // (the tag id)
p[i++] = 4; // (size of the buffer)
p[i++] = 4; // (size of the data)
p[i++] = handle;
p[i++] = 0x00000000; // end tag
p[0] = i*sizeof *p; // actual size
mbox_property(file_desc, p);
return p[5];
}
uint32_t mem_lock(int file_desc, uint32_t handle) {
int i=0;
uint32_t p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x3000d; // (the tag id)
p[i++] = 4; // (size of the buffer)
p[i++] = 4; // (size of the data)
p[i++] = handle;
p[i++] = 0x00000000; // end tag
p[0] = i*sizeof *p; // actual size
if (mbox_property(file_desc, p) < 0)
return ~0;
else
return p[5];
}
uint32_t mem_unlock(int file_desc, uint32_t handle) {
int i=0;
uint32_t p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x3000e; // (the tag id)
p[i++] = 4; // (size of the buffer)
p[i++] = 4; // (size of the data)
p[i++] = handle;
p[i++] = 0x00000000; // end tag
p[0] = i * sizeof(*p); // actual size
mbox_property(file_desc, p);
return p[5];
}
uint32_t execute_code(int file_desc, uint32_t code, uint32_t r0, uint32_t r1,
uint32_t r2, uint32_t r3, uint32_t r4, uint32_t r5) {
int i=0;
uint32_t p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x30010; // (the tag id)
p[i++] = 28; // (size of the buffer)
p[i++] = 28; // (size of the data)
p[i++] = code;
p[i++] = r0;
p[i++] = r1;
p[i++] = r2;
p[i++] = r3;
p[i++] = r4;
p[i++] = r5;
p[i++] = 0x00000000; // end tag
p[0] = i * sizeof(*p); // actual size
mbox_property(file_desc, p);
return p[5];
}
uint32_t qpu_enable(int file_desc, uint32_t enable) {
int i=0;
uint32_t p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x30012; // (the tag id)
p[i++] = 4; // (size of the buffer)
p[i++] = 4; // (size of the data)
p[i++] = enable;
p[i++] = 0x00000000; // end tag
p[0] = i * sizeof(*p); // actual size
mbox_property(file_desc, p);
return p[5];
}
uint32_t execute_qpu(int file_desc, uint32_t num_qpus, uint32_t control,
uint32_t noflush, uint32_t timeout) {
int i = 0;
uint32_t p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x30011; // (the tag id)
p[i++] = 16; // (size of the buffer)
p[i++] = 16; // (size of the data)
p[i++] = num_qpus;
p[i++] = control;
p[i++] = noflush;
p[i++] = timeout; // ms
p[i++] = 0x00000000; // end tag
p[0] = i * sizeof(*p); // actual size
mbox_property(file_desc, p);
return p[5];
}
int mbox_open(void) {
int file_desc;
char filename[64];
file_desc = open("/dev/vcio", 0);
if (file_desc >= 0) {
return file_desc;
}
// open a char device file used for communicating with kernel mbox driver
sprintf(filename, "/tmp/mailbox-%d", getpid());
unlink(filename);
if (mknod(filename, S_IFCHR|0600, makedev(100, 0)) < 0) {
perror("Failed to create mailbox device\n");
return -1;
}
file_desc = open(filename, 0);
if (file_desc < 0) {
perror("Can't open device file\n");
unlink(filename);
return -1;
}
unlink(filename);
return file_desc;
}
void mbox_close(int file_desc) {
close(file_desc);
}

@ -0,0 +1,49 @@
/*
Copyright (c) 2012, Broadcom Europe Ltd.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/ioctl.h>
#define MAJOR_NUM 100
#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *)
#define DEV_MEM "/dev/mem"
#define DEV_GPIOMEM "/dev/gpiomem"
int mbox_open(void);
void mbox_close(int file_desc);
unsigned get_version(int file_desc);
unsigned mem_alloc(int file_desc, unsigned size, unsigned align, unsigned flags);
unsigned mem_free(int file_desc, unsigned handle);
unsigned mem_lock(int file_desc, unsigned handle);
unsigned mem_unlock(int file_desc, unsigned handle);
void *mapmem(unsigned base, unsigned size, const char *mem_dev);
void *unmapmem(void *addr, unsigned size);
unsigned execute_code(int file_desc, unsigned code, unsigned r0, unsigned r1, unsigned r2, unsigned r3, unsigned r4, unsigned r5);
unsigned execute_qpu(int file_desc, unsigned num_qpus, unsigned control, unsigned noflush, unsigned timeout);
unsigned qpu_enable(int file_desc, unsigned enable);

419
main.c

@ -0,0 +1,419 @@
/*
* newtest.c
*
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
static char VERSION[] = "XX.YY.ZZ";
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <signal.h>
#include <stdarg.h>
#include <getopt.h>
#include "clk.h"
#include "gpio.h"
#include "dma.h"
#include "pwm.h"
#include "version.h"
#include "ws2811.h"
#define ARRAY_SIZE(stuff) (sizeof(stuff) / sizeof(stuff[0]))
// defaults for cmdline options
#define TARGET_FREQ WS2811_TARGET_FREQ
#define GPIO_PIN 18
#define DMA 10
//#define STRIP_TYPE WS2811_STRIP_RGB // WS2812/SK6812RGB integrated chip+leds
#define STRIP_TYPE WS2811_STRIP_GBR // WS2812/SK6812RGB integrated chip+leds
//#define STRIP_TYPE SK6812_STRIP_RGBW // SK6812RGBW (NOT SK6812RGB)
#define WIDTH 8
#define HEIGHT 8
#define LED_COUNT (WIDTH * HEIGHT)
int width = WIDTH;
int height = HEIGHT;
int led_count = LED_COUNT;
int clear_on_exit = 0;
ws2811_t ledstring =
{
.freq = TARGET_FREQ,
.dmanum = DMA,
.channel =
{
[0] =
{
.gpionum = GPIO_PIN,
.count = LED_COUNT,
.invert = 0,
.brightness = 255,
.strip_type = STRIP_TYPE,
},
[1] =
</