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');
|
||||
|
@ -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__ */
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
@ -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] =
|
||||