mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2026-01-22 22:17:53 -05:00
Initial commit for Raspberry Pi GPIO ARGB controller
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_RaspberryPi_Linux.cpp |
|
||||
| |
|
||||
| RGBController for Raspberry Pi GPIO ARGB |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Jul 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_RaspberryPi_Linux.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Raspberry Pi
|
||||
@category Motherboard
|
||||
@type GPIO
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectRaspberryPiControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_RaspberryPi::RGBController_RaspberryPi(RaspberryPiController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = "Raspberry Pi";
|
||||
type = DEVICE_TYPE_MOTHERBOARD;
|
||||
vendor = "Raspberry Pi";
|
||||
description = "Raspberry Pi GPIO Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
void RGBController_RaspberryPi::SetupZones()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Only set LED count on the first run |
|
||||
\*-------------------------------------------------*/
|
||||
bool first_run = false;
|
||||
|
||||
if(zones.size() == 0)
|
||||
{
|
||||
first_run = true;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Clear any existing color/LED configuration |
|
||||
\*-------------------------------------------------*/
|
||||
leds.clear();
|
||||
colors.clear();
|
||||
zones.resize(1);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Set zones and leds |
|
||||
\*-------------------------------------------------*/
|
||||
for (unsigned int channel_idx = 0; channel_idx < 1; channel_idx++)
|
||||
{
|
||||
char ch_idx_string[2];
|
||||
snprintf(ch_idx_string, 2, "%d", channel_idx + 1);
|
||||
|
||||
zones[channel_idx].name = "Channel ";
|
||||
zones[channel_idx].name.append(ch_idx_string);
|
||||
zones[channel_idx].type = ZONE_TYPE_LINEAR;
|
||||
zones[channel_idx].leds_min = 0;
|
||||
zones[channel_idx].leds_max = 1000;
|
||||
|
||||
if(first_run)
|
||||
{
|
||||
zones[channel_idx].leds_count = 0;
|
||||
}
|
||||
|
||||
zones[channel_idx].matrix_map = NULL;
|
||||
|
||||
for (unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
|
||||
{
|
||||
char led_idx_string[4];
|
||||
snprintf(led_idx_string, 4, "%d", led_ch_idx + 1);
|
||||
|
||||
led new_led;
|
||||
new_led.name = "Channel ";
|
||||
new_led.name.append(ch_idx_string);
|
||||
new_led.name.append(", LED ");
|
||||
new_led.name.append(led_idx_string);
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
controller->SetSize(zones[0].leds_count);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_RaspberryPi::ResizeZone(int zone, int new_size)
|
||||
{
|
||||
if((size_t) zone >= zones.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
|
||||
{
|
||||
zones[zone].leds_count = new_size;
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_RaspberryPi::DeviceUpdateLEDs()
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
}
|
||||
|
||||
void RGBController_RaspberryPi::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_RaspberryPi::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_RaspberryPi::DeviceUpdateMode()
|
||||
{
|
||||
controller->SetColors(&colors[0]);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_RaspberryPi_Linux.h |
|
||||
| |
|
||||
| RGBController for Raspberry Pi GPIO ARGB |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Jul 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RaspberryPiController_Linux.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
class RGBController_RaspberryPi : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_RaspberryPi(RaspberryPiController* controller_ptr);
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
RaspberryPiController* controller;
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RaspberryPiControllerDetect_Linux.cpp |
|
||||
| |
|
||||
| Detector for Raspberry Pi GPIO ARGB |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Jul 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "Detector.h"
|
||||
#include "RaspberryPiController_Linux.h"
|
||||
#include "RGBController_RaspberryPi_Linux.h"
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectRaspberryPiControllers *
|
||||
* *
|
||||
* Detect Raspberry Pi controllers *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectRaspberryPiControllers()
|
||||
{
|
||||
RaspberryPiController* controller = new RaspberryPiController();
|
||||
|
||||
if(controller->Initialize())
|
||||
{
|
||||
RGBController_RaspberryPi* rgb_controller = new RGBController_RaspberryPi(controller);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("Raspberry Pi", DetectRaspberryPiControllers);
|
||||
@@ -0,0 +1,73 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RaspberryPiController_Linux.cpp |
|
||||
| |
|
||||
| Driver for Raspberry Pi GPIO ARGB |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Jul 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "LogManager.h"
|
||||
#include "RaspberryPiController_Linux.h"
|
||||
|
||||
RaspberryPiController::RaspberryPiController()
|
||||
{
|
||||
memset(&rpi_ws2811, 0x00, sizeof(rpi_ws2811));
|
||||
|
||||
rpi_ws2811.freq = WS2811_TARGET_FREQ;
|
||||
rpi_ws2811.dmanum = RPI_WS2811_DMA;
|
||||
rpi_ws2811.render_wait_time = 0;
|
||||
|
||||
rpi_ws2811.channel[0].gpionum = RPI_WS2811_GPIO;
|
||||
rpi_ws2811.channel[0].invert = 0;
|
||||
rpi_ws2811.channel[0].count = 0;
|
||||
rpi_ws2811.channel[0].strip_type = WS2811_STRIP_GBR;
|
||||
rpi_ws2811.channel[0].brightness = 255;
|
||||
|
||||
rpi_ws2811.channel[1].gpionum = 0;
|
||||
rpi_ws2811.channel[1].invert = 0;
|
||||
rpi_ws2811.channel[1].count = 0;
|
||||
rpi_ws2811.channel[1].strip_type = 0;
|
||||
rpi_ws2811.channel[1].brightness = 0;
|
||||
}
|
||||
|
||||
RaspberryPiController::~RaspberryPiController()
|
||||
{
|
||||
ws2811_fini(&rpi_ws2811);
|
||||
}
|
||||
|
||||
std::string RaspberryPiController::GetDeviceLocation()
|
||||
{
|
||||
return("GPIO: 13, DMA: 10");
|
||||
}
|
||||
|
||||
bool RaspberryPiController::Initialize()
|
||||
{
|
||||
if(ws2811_init(&rpi_ws2811) != WS2811_SUCCESS)
|
||||
{
|
||||
LOG_ERROR( "RaspberryPi: ws2811_init() failure");
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
void RaspberryPiController::SetColors(RGBColor * colors)
|
||||
{
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
rpi_ws2811.channel[0].leds[i] = colors[i];
|
||||
}
|
||||
|
||||
ws2811_render(&rpi_ws2811);
|
||||
}
|
||||
|
||||
void RaspberryPiController::SetSize(unsigned int new_size)
|
||||
{
|
||||
rpi_ws2811.channel[0].count = new_size;
|
||||
|
||||
ws2811_fini(&rpi_ws2811);
|
||||
Initialize();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RaspberryPiController_Linux.h |
|
||||
| |
|
||||
| Driver for Raspberry Pi GPIO ARGB |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 21 Jul 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "RGBController.h"
|
||||
#include "ws2811.h"
|
||||
|
||||
#define RPI_WS2811_DMA 10
|
||||
#define RPI_WS2811_GPIO 18
|
||||
|
||||
class RaspberryPiController
|
||||
{
|
||||
public:
|
||||
RaspberryPiController();
|
||||
~RaspberryPiController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
|
||||
bool Initialize();
|
||||
void SetColors(RGBColor * colors);
|
||||
void SetSize(unsigned int new_size);
|
||||
|
||||
private:
|
||||
ws2811_t rpi_ws2811;
|
||||
};
|
||||
@@ -468,6 +468,9 @@ contains(QMAKE_PLATFORM, linux) {
|
||||
i2c_smbus/i2c_smbus_linux.h \
|
||||
AutoStart/AutoStart-Linux.h \
|
||||
|
||||
INCLUDEPATH += \
|
||||
dependencies/rpi_ws281x/ \
|
||||
|
||||
LIBS += \
|
||||
-lmbedx509 \
|
||||
-lmbedtls \
|
||||
@@ -508,6 +511,12 @@ contains(QMAKE_PLATFORM, linux) {
|
||||
|
||||
SOURCES += \
|
||||
dependencies/hueplusplus-1.1.0/src/LinHttpHandler.cpp \
|
||||
dependencies/rpi_ws281x/dma.c \
|
||||
dependencies/rpi_ws281x/mailbox.c \
|
||||
dependencies/rpi_ws281x/pcm.c \
|
||||
dependencies/rpi_ws281x/pwm.c \
|
||||
dependencies/rpi_ws281x/rpihw.c \
|
||||
dependencies/rpi_ws281x/ws2811.c \
|
||||
i2c_smbus/i2c_smbus_linux.cpp \
|
||||
scsiapi/scsiapi_linux.c \
|
||||
serial_port/find_usb_serial_port_linux.cpp \
|
||||
|
||||
13
dependencies/rpi_ws281x/.gitignore
vendored
Normal file
13
dependencies/rpi_ws281x/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
.sconsign.dblite
|
||||
version.h
|
||||
*.pyc
|
||||
test
|
||||
newtest
|
||||
*.o
|
||||
*.a
|
||||
*.swp
|
||||
|
||||
build/
|
||||
release/
|
||||
debug/
|
||||
settings.json
|
||||
88
dependencies/rpi_ws281x/CMakeLists.txt
vendored
Normal file
88
dependencies/rpi_ws281x/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
# read and parse version file
|
||||
file(READ version PROJECT_VERSION)
|
||||
string(STRIP ${PROJECT_VERSION} PROJECT_VERSION)
|
||||
string(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" VERSION_MAJOR ${PROJECT_VERSION})
|
||||
string(REGEX REPLACE "[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" VERSION_MINOR ${PROJECT_VERSION})
|
||||
string(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" VERSION_MICRO ${PROJECT_VERSION})
|
||||
|
||||
set(HEADERDEF "${VERSION_MAJOR}_${VERSION_MINOR}_${VERSION_MICRO}")
|
||||
|
||||
project(rpi_ws281x VERSION ${PROJECT_VERSION})
|
||||
|
||||
option(BUILD_SHARED "Build as shared library" OFF)
|
||||
option(BUILD_TEST "Build test application" ON)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
set(LIB_TARGET ws2811)
|
||||
set(TEST_TARGET test)
|
||||
|
||||
set(LIB_PUBLIC_HEADERS
|
||||
ws2811.h
|
||||
rpihw.h
|
||||
pwm.h
|
||||
clk.h
|
||||
dma.h
|
||||
gpio.h
|
||||
mailbox.h
|
||||
pcm.h
|
||||
)
|
||||
|
||||
set(LIB_SOURCES
|
||||
mailbox.c
|
||||
ws2811.c
|
||||
pwm.c
|
||||
pcm.c
|
||||
dma.c
|
||||
rpihw.c
|
||||
)
|
||||
|
||||
set(TEST_SOURCES
|
||||
main.c
|
||||
)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
configure_file(version.h.in version.h)
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/libws2811.pc"
|
||||
@ONLY
|
||||
)
|
||||
|
||||
set(DEST_HEADERS_DIR include/ws2811)
|
||||
set(DEST_LIB_DIR lib)
|
||||
|
||||
if(BUILD_SHARED)
|
||||
add_library(${LIB_TARGET} SHARED ${LIB_SOURCES})
|
||||
else()
|
||||
add_library(${LIB_TARGET} ${LIB_SOURCES})
|
||||
endif()
|
||||
|
||||
target_link_libraries(${LIB_TARGET} m)
|
||||
set_target_properties(${LIB_TARGET} PROPERTIES PUBLIC_HEADER "${LIB_PUBLIC_HEADERS}")
|
||||
|
||||
install(TARGETS ${LIB_TARGET}
|
||||
ARCHIVE DESTINATION ${DEST_LIB_DIR}
|
||||
PUBLIC_HEADER DESTINATION ${DEST_HEADERS_DIR}
|
||||
)
|
||||
|
||||
INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/libws2811.pc"
|
||||
DESTINATION lib/pkgconfig)
|
||||
|
||||
install(CODE "execute_process(COMMAND /sbin/ldconfig
|
||||
RESULT_VARIABLE EXIT_STATUS
|
||||
ERROR_QUIET)
|
||||
if (NOT EXIT_STATUS EQUAL 0)
|
||||
message(\"Warning: Could not run ldconfig. You may need to manually run ldconfig as root to cache the newly installed libraries.\")
|
||||
endif()")
|
||||
|
||||
if(BUILD_TEST)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_executable(${TEST_TARGET} ${TEST_SOURCES})
|
||||
target_link_libraries(${TEST_TARGET} ${LIB_TARGET})
|
||||
endif()
|
||||
9
dependencies/rpi_ws281x/DEBIAN/control
vendored
Normal file
9
dependencies/rpi_ws281x/DEBIAN/control
vendored
Normal file
@@ -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.
|
||||
45
dependencies/rpi_ws281x/DEBIAN/postinst
vendored
Normal file
45
dependencies/rpi_ws281x/DEBIAN/postinst
vendored
Normal file
@@ -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
|
||||
~
|
||||
45
dependencies/rpi_ws281x/DEBIAN/postrm
vendored
Normal file
45
dependencies/rpi_ws281x/DEBIAN/postrm
vendored
Normal file
@@ -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
|
||||
~
|
||||
44
dependencies/rpi_ws281x/DEBIAN/prerm
vendored
Normal file
44
dependencies/rpi_ws281x/DEBIAN/prerm
vendored
Normal file
@@ -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
|
||||
|
||||
24
dependencies/rpi_ws281x/LICENSE
vendored
Normal file
24
dependencies/rpi_ws281x/LICENSE
vendored
Normal file
@@ -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.
|
||||
|
||||
235
dependencies/rpi_ws281x/README.md
vendored
Normal file
235
dependencies/rpi_ws281x/README.md
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
rpi_ws281x
|
||||
==========
|
||||
|
||||
Userspace Raspberry Pi library for controlling WS281X LEDs.
|
||||
This includes WS2812 and SK6812RGB RGB LEDs
|
||||
Preliminary support is now included for SK6812RGBW LEDs (yes, RGB + W)
|
||||
The LEDs can be controlled by either the PWM (2 independent channels)
|
||||
or PCM controller (1 channel) or the SPI interface (1 channel).
|
||||
|
||||
### Bindings:
|
||||
|
||||
Language-specific bindings for rpi_ws281x are available in:
|
||||
|
||||
* Python - https://github.com/rpi-ws281x/rpi-ws281x-python
|
||||
* Rust - https://github.com/rpi-ws281x/rpi-ws281x-rust
|
||||
* Powershell - https://github.com/rpi-ws281x/rpi-ws281x-powershell
|
||||
* Java - https://github.com/rpi-ws281x/rpi-ws281x-java
|
||||
* CSharp - https://github.com/rpi-ws281x/rpi-ws281x-csharp
|
||||
* Go - https://github.com/rpi-ws281x/rpi-ws281x-go
|
||||
|
||||
### Background:
|
||||
|
||||
The BCM2835 in the Raspberry Pi has both a PWM and a PCM module that
|
||||
are well suited to driving individually controllable WS281X LEDs.
|
||||
Using the DMA, PWM or PCM FIFO, and serial mode in the PWM, it's
|
||||
possible to control almost any number of WS281X LEDs in a chain connected
|
||||
to the appropriate output pin.
|
||||
For SPI the Raspbian spidev driver is used (`/dev/spidev0.0`).
|
||||
This library and test program set the clock rate to 3X the desired output
|
||||
frequency and creates a bit pattern in RAM from an array of colors where
|
||||
each bit is represented by 3 bits as follows.
|
||||
|
||||
Bit 1 - 1 1 0
|
||||
Bit 0 - 1 0 0
|
||||
|
||||
|
||||
### GPIO Usage:
|
||||
|
||||
The GPIOs that can be used are limited by the hardware of the Pi and will
|
||||
vary based on the method used to drive them (PWM, PCM or SPI).
|
||||
Beware that the GPIO numbers are not the same as the physical pin numbers
|
||||
on the header.
|
||||
|
||||
PWM:
|
||||
```
|
||||
PWM0, which can be set to use GPIOs 12, 18, 40, and 52.
|
||||
Only 12 (pin 32) and 18 (pin 12) are available on the B+/2B/3B
|
||||
|
||||
PWM1 which can be set to use GPIOs 13, 19, 41, 45 and 53.
|
||||
Only 13 is available on the B+/2B/PiZero/3B, on pin 33
|
||||
```
|
||||
|
||||
PCM:
|
||||
```
|
||||
PCM_DOUT, which can be set to use GPIOs 21 and 31.
|
||||
Only 21 is available on the B+/2B/PiZero/3B, on pin 40.
|
||||
```
|
||||
|
||||
SPI:
|
||||
```
|
||||
SPI0-MOSI is available on GPIOs 10 and 38.
|
||||
Only GPIO 10 is available on all models.
|
||||
See also note for RPi 3 below.
|
||||
```
|
||||
|
||||
|
||||
### Power and voltage requirements
|
||||
|
||||
WS281X LEDs are generally driven at 5V. Depending on your actual
|
||||
LED model and data line length you might be able to successfully drive
|
||||
the data input with 3.3V. However in the general case you probably
|
||||
want to use a level shifter to convert from the Raspberry Pi GPIO/PWM to 5V.
|
||||
|
||||
It is also possible to run the LEDs from a 3.3V - 3.6V power source, and
|
||||
connect the GPIO directly at a cost of brightness, but this isn't
|
||||
recommended.
|
||||
|
||||
The test program is designed to drive a 8x8 grid of LEDs e.g.from
|
||||
Adafruit (http://www.adafruit.com/products/1487) or Pimoroni
|
||||
(https://shop.pimoroni.com/products/unicorn-hat).
|
||||
Please see the Adafruit and Pimoroni websites for more information.
|
||||
|
||||
Know what you're doing with the hardware and electricity. I take no
|
||||
reponsibility for damage, harm, or mistakes.
|
||||
|
||||
### Build:
|
||||
|
||||
#### Build with SCons:
|
||||
|
||||
- Install Scons (on raspbian, `apt-get install scons`).
|
||||
- Make sure to adjust the parameters in main.c to suit your hardware.
|
||||
- Signal rate (400kHz to 800kHz). Default 800kHz.
|
||||
- ledstring.invert=1 if using a inverting level shifter.
|
||||
- Width and height of LED matrix (height=1 for LED string).
|
||||
- Type `scons` from inside the source directory.
|
||||
|
||||
#### Build and install with CMake:
|
||||
|
||||
- Install CMake
|
||||
- Configure your build:
|
||||
|
||||
For example:
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -D BUILD_SHARED=OFF -D BUILD_TEST=ON ..
|
||||
```
|
||||
See also for available options in `CMakeLists.txt`.
|
||||
- Type `cmake --build .` to build
|
||||
- To install built binaries and headers into your system type:
|
||||
```
|
||||
sudo make install
|
||||
```
|
||||
|
||||
### Running:
|
||||
|
||||
- Type `sudo ./test` (default uses PWM channel 0).
|
||||
- That's it. You should see a moving rainbow scroll across the
|
||||
display.
|
||||
- More options are available, `./test -h` should show them:
|
||||
```
|
||||
./test version 1.1.0
|
||||
Usage: ./test
|
||||
-h (--help) - this information
|
||||
-s (--strip) - strip type - rgb, grb, gbr, rgbw
|
||||
-x (--width) - matrix width (default 8)
|
||||
-y (--height) - matrix height (default 8)
|
||||
-d (--dma) - dma channel to use (default 10)
|
||||
-g (--gpio) - GPIO to use
|
||||
If omitted, default is 18 (PWM0)
|
||||
-i (--invert) - invert pin output (pulse LOW)
|
||||
-c (--clear) - clear matrix on exit.
|
||||
-v (--version) - version information
|
||||
```
|
||||
|
||||
### Important warning about DMA channels
|
||||
|
||||
You must make sure that the DMA channel you choose to use for the LEDs is not [already in use](https://www.raspberrypi.org/forums/viewtopic.php?p=609380#p609380) by the operating system.
|
||||
|
||||
For example, **using DMA channel 5 [will cause](https://github.com/jgarff/rpi_ws281x/issues/224) filesystem corruption** on the Raspberry Pi 3 Model B.
|
||||
|
||||
The default DMA channel (10) should be safe for the Raspberry Pi 3 Model B, but this may change in future software releases.
|
||||
|
||||
### Limitations:
|
||||
|
||||
#### PWM
|
||||
|
||||
Since this library and the onboard Raspberry Pi audio
|
||||
both use the PWM, they cannot be used together. You will need to
|
||||
blacklist the Broadcom audio kernel module by creating a file
|
||||
`/etc/modprobe.d/snd-blacklist.conf` with
|
||||
|
||||
blacklist snd_bcm2835
|
||||
|
||||
If the audio device is still loading after blacklisting, you may also
|
||||
need to comment it out in the /etc/modules file.
|
||||
|
||||
On headless systems you may also need to force audio through hdmi
|
||||
Edit config.txt and add:
|
||||
|
||||
hdmi_force_hotplug=1
|
||||
hdmi_force_edid_audio=1
|
||||
|
||||
A reboot is required for this change to take effect
|
||||
|
||||
Some distributions use audio by default, even if nothing is being played.
|
||||
If audio is needed, you can use a USB audio device instead.
|
||||
|
||||
#### PCM
|
||||
|
||||
When using PCM you cannot use digital audio devices which use I2S since I2S
|
||||
uses the PCM hardware, but you can use analog audio.
|
||||
|
||||
#### SPI
|
||||
|
||||
When using SPI the led string is the only device which can be connected to
|
||||
the SPI bus. Both digital (I2S/PCM) and analog (PWM) audio can be used.
|
||||
|
||||
Many distributions have a maximum SPI transfer of 4096 bytes. This can be
|
||||
changed in `/boot/cmdline.txt` by appending
|
||||
```
|
||||
spidev.bufsiz=32768
|
||||
```
|
||||
|
||||
On an RPi 3 you have to change the GPU core frequency to 250 MHz, otherwise
|
||||
the SPI clock has the wrong frequency.
|
||||
|
||||
Do this by adding the following line to /boot/config.txt and reboot:
|
||||
|
||||
```
|
||||
core_freq=250
|
||||
```
|
||||
|
||||
On an RPi 4 you must set a fixed frequency to avoid the idle CPU scaling changing the SPI frequency and breaking the ws281x timings:
|
||||
|
||||
Do this by adding the following lines to /boot/config.txt and reboot:
|
||||
|
||||
```
|
||||
core_freq=500
|
||||
core_freq_min=500
|
||||
```
|
||||
|
||||
SPI requires you to be in the `gpio` group if you wish to control your LEDs
|
||||
without root.
|
||||
|
||||
### Comparison PWM/PCM/SPI
|
||||
|
||||
Both PWM and PCM use DMA transfer to output the control signal for the LEDs.
|
||||
The max size of a DMA transfer is 65536 bytes. Since each LED needs 12 bytes
|
||||
(4 colors, 8 symbols per color, 3 bits per symbol) this means you can
|
||||
control approximately 5400 LEDs for a single strand in PCM and 2700 LEDs per string
|
||||
for PWM (Only PWM can control 2 independent strings simultaneously)
|
||||
SPI uses the SPI device driver in the kernel. For transfers larger than
|
||||
96 bytes the kernel driver also uses DMA.
|
||||
Of course there are practical limits on power and signal quality. These will
|
||||
be more constraining in practice than the theoretical limits above.
|
||||
|
||||
When controlling a LED string of 240 LEDs the CPU load on the original Pi 2 (BCM2836) are:
|
||||
PWM 5%
|
||||
PCM 5%
|
||||
SPI 1%
|
||||
|
||||
### Usage:
|
||||
|
||||
The API is very simple. Make sure to create and initialize the `ws2811_t`
|
||||
structure as seen in [`main.c`](main.c). From there it can be initialized
|
||||
by calling `ws2811_init()`. LEDs are changed by modifying the color in
|
||||
the `.led[index]` array and calling `ws2811_render()`.
|
||||
The rest is handled by the library, which either creates the DMA memory and
|
||||
starts the DMA for PWM and PCM or prepares the SPI transfer buffer and sends
|
||||
it out on the MISO pin.
|
||||
|
||||
Make sure to hook a signal handler for SIGKILL to do cleanup. From the
|
||||
handler make sure to call `ws2811_fini()`. It'll make sure that the DMA
|
||||
is finished before program execution stops and cleans up after itself.
|
||||
95
dependencies/rpi_ws281x/SConscript
vendored
Normal file
95
dependencies/rpi_ws281x/SConscript
vendored
Normal file
@@ -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", 0o755)
|
||||
])
|
||||
)
|
||||
|
||||
package = tools_env.Command('%s.deb' % package_name, package_files,
|
||||
'cd %s; dpkg-deb --build %s' % (Dir('.').abspath, package_name));
|
||||
|
||||
Alias("deb", package)
|
||||
|
||||
77
dependencies/rpi_ws281x/SConstruct
vendored
Normal file
77
dependencies/rpi_ws281x/SConstruct
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
#
|
||||
# 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",
|
||||
"-lm",
|
||||
],
|
||||
},
|
||||
],
|
||||
]
|
||||
|
||||
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');
|
||||
|
||||
66
dependencies/rpi_ws281x/clk.h
vendored
Normal file
66
dependencies/rpi_ws281x/clk.h
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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__
|
||||
|
||||
#include <stdint.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
dependencies/rpi_ws281x/dma.c
vendored
Normal file
78
dependencies/rpi_ws281x/dma.c
vendored
Normal file
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
127
dependencies/rpi_ws281x/dma.h
vendored
Normal file
127
dependencies/rpi_ws281x/dma.h
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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__
|
||||
|
||||
#include <stdint.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__ */
|
||||
109
dependencies/rpi_ws281x/gpio.h
vendored
Normal file
109
dependencies/rpi_ws281x/gpio.h
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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__
|
||||
|
||||
#include <stdint.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__ */
|
||||
84
dependencies/rpi_ws281x/linux.py
vendored
Normal file
84
dependencies/rpi_ws281x/linux.py
vendored
Normal file
@@ -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)]
|
||||
|
||||
292
dependencies/rpi_ws281x/mailbox.c
vendored
Normal file
292
dependencies/rpi_ws281x/mailbox.c
vendored
Normal file
@@ -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);
|
||||
}
|
||||
49
dependencies/rpi_ws281x/mailbox.h
vendored
Normal file
49
dependencies/rpi_ws281x/mailbox.h
vendored
Normal file
@@ -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
dependencies/rpi_ws281x/main.c
vendored
Normal file
419
dependencies/rpi_ws281x/main.c
vendored
Normal file
@@ -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,
|
||||
.invert = 0,
|
||||
.count = LED_COUNT,
|
||||
.strip_type = STRIP_TYPE,
|
||||
.brightness = 255,
|
||||
},
|
||||
[1] =
|
||||
{
|
||||
.gpionum = 0,
|
||||
.invert = 0,
|
||||
.count = 0,
|
||||
.brightness = 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
ws2811_led_t *matrix;
|
||||
|
||||
static uint8_t running = 1;
|
||||
|
||||
void matrix_render(void)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
ledstring.channel[0].leds[(y * width) + x] = matrix[y * width + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_raise(void)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < (height - 1); y++)
|
||||
{
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
// This is for the 8x8 Pimoroni Unicorn-HAT where the LEDS in subsequent
|
||||
// rows are arranged in opposite directions
|
||||
matrix[y * width + x] = matrix[(y + 1)*width + width - x - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_clear(void)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < (height ); y++)
|
||||
{
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
matrix[y * width + x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int dotspos[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
ws2811_led_t dotcolors[] =
|
||||
{
|
||||
0x00200000, // red
|
||||
0x00201000, // orange
|
||||
0x00202000, // yellow
|
||||
0x00002000, // green
|
||||
0x00002020, // lightblue
|
||||
0x00000020, // blue
|
||||
0x00100010, // purple
|
||||
0x00200010, // pink
|
||||
};
|
||||
|
||||
ws2811_led_t dotcolors_rgbw[] =
|
||||
{
|
||||
0x00200000, // red
|
||||
0x10200000, // red + W
|
||||
0x00002000, // green
|
||||
0x10002000, // green + W
|
||||
0x00000020, // blue
|
||||
0x10000020, // blue + W
|
||||
0x00101010, // white
|
||||
0x10101010, // white + W
|
||||
|
||||
};
|
||||
|
||||
void matrix_bottom(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (int)(ARRAY_SIZE(dotspos)); i++)
|
||||
{
|
||||
dotspos[i]++;
|
||||
if (dotspos[i] > (width - 1))
|
||||
{
|
||||
dotspos[i] = 0;
|
||||
}
|
||||
|
||||
if (ledstring.channel[0].strip_type == SK6812_STRIP_RGBW) {
|
||||
matrix[dotspos[i] + (height - 1) * width] = dotcolors_rgbw[i];
|
||||
} else {
|
||||
matrix[dotspos[i] + (height - 1) * width] = dotcolors[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ctrl_c_handler(int signum)
|
||||
{
|
||||
(void)(signum);
|
||||
running = 0;
|
||||
}
|
||||
|
||||
static void setup_handlers(void)
|
||||
{
|
||||
struct sigaction sa =
|
||||
{
|
||||
.sa_handler = ctrl_c_handler,
|
||||
};
|
||||
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
}
|
||||
|
||||
|
||||
void parseargs(int argc, char **argv, ws2811_t *ws2811)
|
||||
{
|
||||
int index;
|
||||
int c;
|
||||
|
||||
static struct option longopts[] =
|
||||
{
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"dma", required_argument, 0, 'd'},
|
||||
{"gpio", required_argument, 0, 'g'},
|
||||
{"invert", no_argument, 0, 'i'},
|
||||
{"clear", no_argument, 0, 'c'},
|
||||
{"strip", required_argument, 0, 's'},
|
||||
{"height", required_argument, 0, 'y'},
|
||||
{"width", required_argument, 0, 'x'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
index = 0;
|
||||
c = getopt_long(argc, argv, "cd:g:his:vx:y:", longopts, &index);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
/* handle flag options (array's 3rd field non-0) */
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
fprintf(stderr, "%s version %s\n", argv[0], VERSION);
|
||||
fprintf(stderr, "Usage: %s \n"
|
||||
"-h (--help) - this information\n"
|
||||
"-s (--strip) - strip type - rgb, grb, gbr, rgbw\n"
|
||||
"-x (--width) - matrix width (default 8)\n"
|
||||
"-y (--height) - matrix height (default 8)\n"
|
||||
"-d (--dma) - dma channel to use (default 10)\n"
|
||||
"-g (--gpio) - GPIO to use\n"
|
||||
" If omitted, default is 18 (PWM0)\n"
|
||||
"-i (--invert) - invert pin output (pulse LOW)\n"
|
||||
"-c (--clear) - clear matrix on exit.\n"
|
||||
"-v (--version) - version information\n"
|
||||
, argv[0]);
|
||||
exit(-1);
|
||||
|
||||
case 'D':
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
if (optarg) {
|
||||
int gpio = atoi(optarg);
|
||||
/*
|
||||
PWM0, which can be set to use GPIOs 12, 18, 40, and 52.
|
||||
Only 12 (pin 32) and 18 (pin 12) are available on the B+/2B/3B
|
||||
PWM1 which can be set to use GPIOs 13, 19, 41, 45 and 53.
|
||||
Only 13 is available on the B+/2B/PiZero/3B, on pin 33
|
||||
PCM_DOUT, which can be set to use GPIOs 21 and 31.
|
||||
Only 21 is available on the B+/2B/PiZero/3B, on pin 40.
|
||||
SPI0-MOSI is available on GPIOs 10 and 38.
|
||||
Only GPIO 10 is available on all models.
|
||||
|
||||
The library checks if the specified gpio is available
|
||||
on the specific model (from model B rev 1 till 3B)
|
||||
|
||||
*/
|
||||
ws2811->channel[0].gpionum = gpio;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
ws2811->channel[0].invert=1;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
clear_on_exit=1;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (optarg) {
|
||||
int dma = atoi(optarg);
|
||||
if (dma < 14) {
|
||||
ws2811->dmanum = dma;
|
||||
} else {
|
||||
printf ("invalid dma %d\n", dma);
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
if (optarg) {
|
||||
height = atoi(optarg);
|
||||
if (height > 0) {
|
||||
ws2811->channel[0].count = height * width;
|
||||
} else {
|
||||
printf ("invalid height %d\n", height);
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
if (optarg) {
|
||||
width = atoi(optarg);
|
||||
if (width > 0) {
|
||||
ws2811->channel[0].count = height * width;
|
||||
} else {
|
||||
printf ("invalid width %d\n", width);
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (optarg) {
|
||||
if (!strncasecmp("rgb", optarg, 4)) {
|
||||
ws2811->channel[0].strip_type = WS2811_STRIP_RGB;
|
||||
}
|
||||
else if (!strncasecmp("rbg", optarg, 4)) {
|
||||
ws2811->channel[0].strip_type = WS2811_STRIP_RBG;
|
||||
}
|
||||
else if (!strncasecmp("grb", optarg, 4)) {
|
||||
ws2811->channel[0].strip_type = WS2811_STRIP_GRB;
|
||||
}
|
||||
else if (!strncasecmp("gbr", optarg, 4)) {
|
||||
ws2811->channel[0].strip_type = WS2811_STRIP_GBR;
|
||||
}
|
||||
else if (!strncasecmp("brg", optarg, 4)) {
|
||||
ws2811->channel[0].strip_type = WS2811_STRIP_BRG;
|
||||
}
|
||||
else if (!strncasecmp("bgr", optarg, 4)) {
|
||||
ws2811->channel[0].strip_type = WS2811_STRIP_BGR;
|
||||
}
|
||||
else if (!strncasecmp("rgbw", optarg, 4)) {
|
||||
ws2811->channel[0].strip_type = SK6812_STRIP_RGBW;
|
||||
}
|
||||
else if (!strncasecmp("grbw", optarg, 4)) {
|
||||
ws2811->channel[0].strip_type = SK6812_STRIP_GRBW;
|
||||
}
|
||||
else {
|
||||
printf ("invalid strip %s\n", optarg);
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
fprintf(stderr, "%s version %s\n", argv[0], VERSION);
|
||||
exit(-1);
|
||||
|
||||
case '?':
|
||||
/* getopt_long already reported error? */
|
||||
exit(-1);
|
||||
|
||||
default:
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ws2811_return_t ret;
|
||||
|
||||
sprintf(VERSION, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
|
||||
|
||||
parseargs(argc, argv, &ledstring);
|
||||
|
||||
matrix = malloc(sizeof(ws2811_led_t) * width * height);
|
||||
|
||||
setup_handlers();
|
||||
|
||||
if ((ret = ws2811_init(&ledstring)) != WS2811_SUCCESS)
|
||||
{
|
||||
fprintf(stderr, "ws2811_init failed: %s\n", ws2811_get_return_t_str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (running)
|
||||
{
|
||||
matrix_raise();
|
||||
matrix_bottom();
|
||||
matrix_render();
|
||||
|
||||
if ((ret = ws2811_render(&ledstring)) != WS2811_SUCCESS)
|
||||
{
|
||||
fprintf(stderr, "ws2811_render failed: %s\n", ws2811_get_return_t_str(ret));
|
||||
break;
|
||||
}
|
||||
|
||||
// 15 frames /sec
|
||||
usleep(1000000 / 15);
|
||||
}
|
||||
|
||||
if (clear_on_exit) {
|
||||
matrix_clear();
|
||||
matrix_render();
|
||||
ws2811_render(&ledstring);
|
||||
}
|
||||
|
||||
ws2811_fini(&ledstring);
|
||||
|
||||
printf ("\n");
|
||||
return ret;
|
||||
}
|
||||
127
dependencies/rpi_ws281x/pcm.c
vendored
Normal file
127
dependencies/rpi_ws281x/pcm.c
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* pcm.c
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
|
||||
* PCM version Copyright (c) 2016 Ton van Overbeek <tvoverbeek @ gmail.com>
|
||||
*
|
||||
* 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 "pcm.h"
|
||||
|
||||
|
||||
// Mapping of Pin to alternate function for PCM_CLK
|
||||
const pcm_pin_table_t pcm_pin_clk[] =
|
||||
{
|
||||
{
|
||||
.pinnum = 18,
|
||||
.altnum = 0,
|
||||
},
|
||||
{
|
||||
.pinnum = 28,
|
||||
.altnum = 2,
|
||||
},
|
||||
};
|
||||
|
||||
// Mapping of Pin to alternate function for PCM_FS
|
||||
const pcm_pin_table_t pcm_pin_fs[] =
|
||||
{
|
||||
{
|
||||
.pinnum = 19,
|
||||
.altnum = 0,
|
||||
},
|
||||
{
|
||||
.pinnum = 29,
|
||||
.altnum = 2,
|
||||
},
|
||||
};
|
||||
|
||||
// Mapping of Pin to alternate function for PCM_DIN
|
||||
const pcm_pin_table_t pcm_pin_din[] =
|
||||
{
|
||||
{
|
||||
.pinnum = 20,
|
||||
.altnum = 0,
|
||||
},
|
||||
{
|
||||
.pinnum = 30,
|
||||
.altnum = 2,
|
||||
},
|
||||
};
|
||||
|
||||
// Mapping of Pin to alternate function for PCM_DOUT
|
||||
const pcm_pin_table_t pcm_pin_dout[] =
|
||||
{
|
||||
{
|
||||
.pinnum = 21,
|
||||
.altnum = 0,
|
||||
},
|
||||
{
|
||||
.pinnum = 31,
|
||||
.altnum = 2,
|
||||
},
|
||||
};
|
||||
|
||||
const pcm_pin_tables_t pcm_pin_tables[NUM_PCMFUNS] =
|
||||
{
|
||||
{
|
||||
.pins = pcm_pin_clk,
|
||||
.count = sizeof(pcm_pin_clk) / sizeof(pcm_pin_clk[0]),
|
||||
},
|
||||
{
|
||||
.pins = pcm_pin_fs,
|
||||
.count = sizeof(pcm_pin_fs) / sizeof(pcm_pin_fs[0]),
|
||||
},
|
||||
{
|
||||
.pins = pcm_pin_din,
|
||||
.count = sizeof(pcm_pin_din) / sizeof(pcm_pin_din[0]),
|
||||
},
|
||||
{
|
||||
.pins = pcm_pin_dout,
|
||||
.count = sizeof(pcm_pin_dout) / sizeof(pcm_pin_dout[0]),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
int pcm_pin_alt(int pcmfun, int pinnum)
|
||||
{
|
||||
if (pcmfun < 0 || pcmfun > 3) {
|
||||
return -1;
|
||||
}
|
||||
const pcm_pin_tables_t *pintable = &pcm_pin_tables[pcmfun];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pintable->count; i++)
|
||||
{
|
||||
if (pintable->pins[i].pinnum == pinnum)
|
||||
{
|
||||
return pintable->pins[i].altnum;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
159
dependencies/rpi_ws281x/pcm.h
vendored
Normal file
159
dependencies/rpi_ws281x/pcm.h
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* pcm.h
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
|
||||
* PCM version Copyright (c) Ton van Overbeek <tvoverbeek @ gmail.com>
|
||||
*
|
||||
* 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 __PCM_H__
|
||||
#define __PCM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
*
|
||||
* Pin mapping of alternate pin configuration for PCM
|
||||
*
|
||||
* GPIO ALT PCM_CLK ALT PCM-FS ALT PCM_DIN ALT PCM_DOUT
|
||||
*
|
||||
* 18 0
|
||||
* 19 0
|
||||
* 20 0
|
||||
* 21 0
|
||||
* 28 2
|
||||
* 29 2
|
||||
* 30 2
|
||||
* 31 2
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t cs;
|
||||
#define RPI_PCM_CS_STBY (1 << 25)
|
||||
#define RPI_PCM_CS_SYNC (1 << 24)
|
||||
#define RPI_PCM_CS_RXSEX (1 << 23)
|
||||
#define RPI_PCM_CS_RXF (1 << 22)
|
||||
#define RPI_PCM_CS_TXE (1 << 21)
|
||||
#define RPI_PCM_CS_RXD (1 << 20)
|
||||
#define RPI_PCM_CS_TXD (1 << 19)
|
||||
#define RPI_PCM_CS_RXR (1 << 18)
|
||||
#define RPI_PCM_CS_TXW (1 << 17)
|
||||
#define RPI_PCM_CS_RXERR (1 << 16)
|
||||
#define RPI_PCM_CS_TXERR (1 << 15)
|
||||
#define RPI_PCM_CS_RXSYNC (1 << 14)
|
||||
#define RPI_PCM_CS_TXSYNC (1 << 13)
|
||||
#define RPI_PCM_CS_DMAEN (1 << 9)
|
||||
#define RPI_PCM_CS_RXTHR(val) ((val & 0x03) << 7)
|
||||
#define RPI_PCM_CS_TXTHR(val) ((val & 0x03) << 5)
|
||||
#define RPI_PCM_CS_RXCLR (1 << 4)
|
||||
#define RPI_PCM_CS_TXCLR (1 << 3)
|
||||
#define RPI_PCM_CS_TXON (1 << 2)
|
||||
#define RPI_PCM_CS_RXON (1 << 1)
|
||||
#define RPI_PCM_CS_EN (1 << 0)
|
||||
uint32_t fifo;
|
||||
uint32_t mode;
|
||||
#define RPI_PCM_MODE_CLK_DIS (1 << 28)
|
||||
#define RPI_PCM_MODE_PDMN (1 << 27)
|
||||
#define RPI_PCM_MODE_PDME (1 << 26)
|
||||
#define RPI_PCM_MODE_FRXP (1 << 25)
|
||||
#define RPI_PCM_MODE_FTXP (1 << 24)
|
||||
#define RPI_PCM_MODE_CLKM (1 << 23)
|
||||
#define RPI_PCM_MODE_CLKI (1 << 22)
|
||||
#define RPI_PCM_MODE_FSM (1 << 21)
|
||||
#define RPI_PCM_MODE_FSI (1 << 20)
|
||||
#define RPI_PCM_MODE_FLEN(val) ((val & 0x3ff) << 10)
|
||||
#define RPI_PCM_MODE_FSLEN(val) ((val & 0x3ff) << 0)
|
||||
uint32_t rxc;
|
||||
#define RPI_PCM_RXC_CH1WEX (1 << 31)
|
||||
#define RPI_PCM_RXC_CH1EN (1 << 30)
|
||||
#define RPI_PCM_RXC_CH1POS(val) ((val & 0x3ff) << 20)
|
||||
#define RPI_PCM_RXC_CH1WID(val) ((val & 0x0f) << 16)
|
||||
#define RPI_PCM_RXC_CH2WEX (1 << 15)
|
||||
#define RPI_PCM_RXC_CH2EN (1 << 14)
|
||||
#define RPI_PCM_RXC_CH2POS(val) ((val & 0x3ff) << 4)
|
||||
#define RPI_PCM_RXC_CH2WID(val) ((val & 0x0f) << 0)
|
||||
uint32_t txc;
|
||||
#define RPI_PCM_TXC_CH1WEX (1 << 31)
|
||||
#define RPI_PCM_TXC_CH1EN (1 << 30)
|
||||
#define RPI_PCM_TXC_CH1POS(val) ((val & 0x3ff) << 20)
|
||||
#define RPI_PCM_TXC_CH1WID(val) ((val & 0x0f) << 16)
|
||||
#define RPI_PCM_TXC_CH2WEX (1 << 15)
|
||||
#define RPI_PCM_TXC_CH2EN (1 << 14)
|
||||
#define RPI_PCM_TXC_CH2POS(val) ((val & 0x3ff) << 4)
|
||||
#define RPI_PCM_TXC_CH2WID(val) ((val & 0x0f) << 0)
|
||||
uint32_t dreq;
|
||||
#define RPI_PCM_DREQ_TX_PANIC(val) ((val & 0x7f) << 24)
|
||||
#define RPI_PCM_DREQ_RX_PANIC(val) ((val & 0x7f) << 16)
|
||||
#define RPI_PCM_DREQ_TX(val) ((val & 0x7f) << 8)
|
||||
#define RPI_PCM_DREQ_RX(val) ((val & 0x7f) << 0)
|
||||
uint32_t inten;
|
||||
#define RPI_PCM_INTEN_RXERR (1 << 3)
|
||||
#define RPI_PCM_INTEN_TXERR (1 << 2)
|
||||
#define RPI_PCM_INTEN_RXR (1 << 1)
|
||||
#define RPI_PCM_INTEN_TXW (1 << 0)
|
||||
uint32_t intstc;
|
||||
#define RPI_PCM_INTSTC_RXERR (1 << 3)
|
||||
#define RPI_PCM_INTSTC_TXERR (1 << 2)
|
||||
#define RPI_PCM_INTSTC_RXR (1 << 1)
|
||||
#define RPI_PCM_INTSTC_TXW (1 << 0)
|
||||
uint32_t gray;
|
||||
#define RPI_PCM_GRAY_RXFIFOLEVEL(val) ((val & 0x3f) << 16)
|
||||
#define RPI_PCM_GRAY_FLUSHED(val) ((val & 0x3f) << 10
|
||||
#define RPI_PCM_GRAY_RXLEVEL(val) ((val & 0x3f) << 4)
|
||||
#define RPI_PCM_GRAY_FLUSH (1 << 2)
|
||||
#define RPI_PCM_GRAY_CLR (1 << 1)
|
||||
#define RPI_PCM_GRAY_EN (1 << 0)
|
||||
} __attribute__((packed, aligned(4))) pcm_t;
|
||||
|
||||
|
||||
#define PCM_OFFSET (0x00203000)
|
||||
#define PCM_PERIPH_PHYS (0x7e203000)
|
||||
|
||||
#define NUM_PCMFUNS 4
|
||||
#define PCMFUN_CLK 0
|
||||
#define PCMFUN_FS 1
|
||||
#define PCMFUN_DIN 2
|
||||
#define PCMFUN_DOUT 3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int pinnum;
|
||||
int altnum;
|
||||
} pcm_pin_table_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const int count;
|
||||
const pcm_pin_table_t *pins;
|
||||
} pcm_pin_tables_t;
|
||||
|
||||
|
||||
int pcm_pin_alt(int pcmfun, int pinnum);
|
||||
|
||||
|
||||
#endif /* __PCM_H__ */
|
||||
9
dependencies/rpi_ws281x/pkg-config.pc.in
vendored
Normal file
9
dependencies/rpi_ws281x/pkg-config.pc.in
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@/ws2811
|
||||
|
||||
Name: libws2811
|
||||
Description: Raspberry Pi WS281X Library
|
||||
Version: @VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_MICRO@
|
||||
Requires:
|
||||
Libs: -L${libdir} -lws2811
|
||||
Cflags: -I${includedir}
|
||||
104
dependencies/rpi_ws281x/pwm.c
vendored
Normal file
104
dependencies/rpi_ws281x/pwm.c
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* pwm.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 "ws2811.h"
|
||||
|
||||
#include "pwm.h"
|
||||
|
||||
|
||||
// Mapping of Pin to alternate function for PWM channel 0
|
||||
const pwm_pin_table_t pwm_pin_chan0[] =
|
||||
{
|
||||
{
|
||||
.pinnum = 12,
|
||||
.altnum = 0,
|
||||
},
|
||||
{
|
||||
.pinnum = 18,
|
||||
.altnum = 5,
|
||||
},
|
||||
{
|
||||
.pinnum = 40,
|
||||
.altnum = 0,
|
||||
},
|
||||
};
|
||||
|
||||
// Mapping of Pin to alternate function for PWM channel 1
|
||||
const pwm_pin_table_t pwm_pin_chan1[] =
|
||||
{
|
||||
{
|
||||
.pinnum = 13,
|
||||
.altnum = 0,
|
||||
},
|
||||
{
|
||||
.pinnum = 19,
|
||||
.altnum = 5,
|
||||
},
|
||||
{
|
||||
.pinnum = 41,
|
||||
.altnum = 0,
|
||||
},
|
||||
{
|
||||
.pinnum = 45,
|
||||
.altnum = 0,
|
||||
},
|
||||
};
|
||||
|
||||
const pwm_pin_tables_t pwm_pin_tables[RPI_PWM_CHANNELS] =
|
||||
{
|
||||
{
|
||||
.pins = pwm_pin_chan0,
|
||||
.count = sizeof(pwm_pin_chan0) / sizeof(pwm_pin_chan0[0]),
|
||||
},
|
||||
{
|
||||
.pins = pwm_pin_chan1,
|
||||
.count = sizeof(pwm_pin_chan1) / sizeof(pwm_pin_chan1[0]),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
int pwm_pin_alt(int chan, int pinnum)
|
||||
{
|
||||
const pwm_pin_tables_t *pintable = &pwm_pin_tables[chan];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pintable->count; i++)
|
||||
{
|
||||
if (pintable->pins[i].pinnum == pinnum)
|
||||
{
|
||||
return pintable->pins[i].altnum;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
123
dependencies/rpi_ws281x/pwm.h
vendored
Normal file
123
dependencies/rpi_ws281x/pwm.h
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* pwm.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 __PWM_H__
|
||||
#define __PWM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
*
|
||||
* Pin mappint of alternate pin configuration for PWM
|
||||
*
|
||||
* GPIO ALT PWM0 ALT PWM1
|
||||
*
|
||||
* 12 0
|
||||
* 13 0
|
||||
* 18 5
|
||||
* 19 5
|
||||
* 40 0
|
||||
* 41 0
|
||||
* 45 0
|
||||
* 52 1
|
||||
* 53 1
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define RPI_PWM_CHANNELS 2
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t ctl;
|
||||
#define RPI_PWM_CTL_MSEN2 (1 << 15)
|
||||
#define RPI_PWM_CTL_USEF2 (1 << 13)
|
||||
#define RPI_PWM_CTL_POLA2 (1 << 12)
|
||||
#define RPI_PWM_CTL_SBIT2 (1 << 11)
|
||||
#define RPI_PWM_CTL_RPTL2 (1 << 10)
|
||||
#define RPI_PWM_CTL_MODE2 (1 << 9)
|
||||
#define RPI_PWM_CTL_PWEN2 (1 << 8)
|
||||
#define RPI_PWM_CTL_MSEN1 (1 << 7)
|
||||
#define RPI_PWM_CTL_CLRF1 (1 << 6)
|
||||
#define RPI_PWM_CTL_USEF1 (1 << 5)
|
||||
#define RPI_PWM_CTL_POLA1 (1 << 4)
|
||||
#define RPI_PWM_CTL_SBIT1 (1 << 3)
|
||||
#define RPI_PWM_CTL_RPTL1 (1 << 2)
|
||||
#define RPI_PWM_CTL_MODE1 (1 << 1)
|
||||
#define RPI_PWM_CTL_PWEN1 (1 << 0)
|
||||
uint32_t sta;
|
||||
#define RPI_PWM_STA_STA4 (1 << 12)
|
||||
#define RPI_PWM_STA_STA3 (1 << 11)
|
||||
#define RPI_PWM_STA_STA2 (1 << 10)
|
||||
#define RPI_PWM_STA_STA1 (1 << 9)
|
||||
#define RPI_PWM_STA_BERR (1 << 8)
|
||||
#define RPI_PWM_STA_GAP04 (1 << 7)
|
||||
#define RPI_PWM_STA_GAP03 (1 << 6)
|
||||
#define RPI_PWM_STA_GAP02 (1 << 5)
|
||||
#define RPI_PWM_STA_GAP01 (1 << 4)
|
||||
#define RPI_PWM_STA_RERR1 (1 << 3)
|
||||
#define RPI_PWM_STA_WERR1 (1 << 2)
|
||||
#define RPI_PWM_STA_EMPT1 (1 << 1)
|
||||
#define RPI_PWM_STA_FULL1 (1 << 0)
|
||||
uint32_t dmac;
|
||||
#define RPI_PWM_DMAC_ENAB (1 << 31)
|
||||
#define RPI_PWM_DMAC_PANIC(val) ((val & 0xff) << 8)
|
||||
#define RPI_PWM_DMAC_DREQ(val) ((val & 0xff) << 0)
|
||||
uint32_t resvd_0x0c;
|
||||
uint32_t rng1;
|
||||
uint32_t dat1;
|
||||
uint32_t fif1;
|
||||
uint32_t resvd_0x1c;
|
||||
uint32_t rng2;
|
||||
uint32_t dat2;
|
||||
} __attribute__((packed, aligned(4))) pwm_t;
|
||||
|
||||
|
||||
#define PWM_OFFSET (0x0020c000)
|
||||
#define PWM_PERIPH_PHYS (0x7e20c000)
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int pinnum;
|
||||
int altnum;
|
||||
} pwm_pin_table_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const int count;
|
||||
const pwm_pin_table_t *pins;
|
||||
} pwm_pin_tables_t;
|
||||
|
||||
|
||||
int pwm_pin_alt(int chan, int pinnum);
|
||||
|
||||
|
||||
#endif /* __PWM_H__ */
|
||||
637
dependencies/rpi_ws281x/rpihw.c
vendored
Normal file
637
dependencies/rpi_ws281x/rpihw.c
vendored
Normal file
@@ -0,0 +1,637 @@
|
||||
/*
|
||||
* rpihw.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 <errno.h>
|
||||
#include <byteswap.h>
|
||||
|
||||
#include "rpihw.h"
|
||||
|
||||
|
||||
#define LINE_WIDTH_MAX 80
|
||||
#define HW_VER_STRING "Revision"
|
||||
|
||||
#define PERIPH_BASE_RPI 0x20000000
|
||||
#define PERIPH_BASE_RPI2 0x3f000000
|
||||
#define PERIPH_BASE_RPI4 0xfe000000
|
||||
|
||||
#define VIDEOCORE_BASE_RPI 0x40000000
|
||||
#define VIDEOCORE_BASE_RPI2 0xc0000000
|
||||
|
||||
#define RPI_MANUFACTURER_MASK (0xf << 16)
|
||||
#define RPI_WARRANTY_MASK (0x3 << 24)
|
||||
|
||||
static const rpi_hw_t rpi_hw_info[] = {
|
||||
//
|
||||
// Raspberry Pi 400
|
||||
//
|
||||
{
|
||||
.hwver = 0xc03130,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 400 - 4GB v1.0"
|
||||
},
|
||||
{
|
||||
.hwver = 0xc03131,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 400 - 4GB v1.1"
|
||||
},
|
||||
|
||||
//
|
||||
// Raspberry Pi 4
|
||||
//
|
||||
{
|
||||
.hwver = 0xA03111,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 1GB v1.1"
|
||||
},
|
||||
{
|
||||
.hwver = 0xB03111,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 2GB v.1.1"
|
||||
},
|
||||
{
|
||||
.hwver = 0xC03111,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 4GB v1.1"
|
||||
},
|
||||
{
|
||||
.hwver = 0xA03112,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 1GB v1.2"
|
||||
},
|
||||
{
|
||||
.hwver = 0xB03112,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 2GB v.1.2"
|
||||
},
|
||||
{
|
||||
.hwver = 0xC03112,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 4GB v1.2"
|
||||
},
|
||||
{
|
||||
.hwver = 0xb03114,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 2GB v1.4"
|
||||
},
|
||||
{
|
||||
.hwver = 0xD03114,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 8GB v1.4"
|
||||
},
|
||||
{
|
||||
.hwver = 0xc03114,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 4GB v1.4"
|
||||
},
|
||||
{
|
||||
.hwver = 0xa03115,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 1GB v1.5"
|
||||
},
|
||||
{
|
||||
.hwver = 0xb03115,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 2GB v1.5"
|
||||
},
|
||||
{
|
||||
.hwver = 0xc03115,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 4GB v1.5"
|
||||
},
|
||||
{
|
||||
.hwver = 0xd03115,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 4 Model B - 8GB v1.5"
|
||||
},
|
||||
|
||||
//
|
||||
// Compute Module 4
|
||||
//
|
||||
{
|
||||
.hwver = 0xa03140,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 4 v1.0 eMMC"
|
||||
},
|
||||
{
|
||||
.hwver = 0xb03140,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 4 v1.0 Lite"
|
||||
},
|
||||
{
|
||||
.hwver = 0xc03140,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 4 v1.0 WiFi"
|
||||
},
|
||||
{
|
||||
.hwver = 0xd03140,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 4 v1.0 WiFi 8GB"
|
||||
},
|
||||
{
|
||||
.hwver = 0xa03141,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 4 Rev 1.1"
|
||||
},
|
||||
{
|
||||
.hwver = 0xb03141,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 4 Rev 1.1"
|
||||
},
|
||||
{
|
||||
.hwver = 0xc03141,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 4 Rev 1.1"
|
||||
},
|
||||
{
|
||||
.hwver = 0xd03141,
|
||||
.type = RPI_HWVER_TYPE_PI4,
|
||||
.periph_base = PERIPH_BASE_RPI4,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 4 Rev 1.1"
|
||||
},
|
||||
|
||||
//
|
||||
// Model B Rev 1.0
|
||||
//
|
||||
{
|
||||
.hwver = 0x02,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B",
|
||||
},
|
||||
{
|
||||
.hwver = 0x03,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B",
|
||||
},
|
||||
|
||||
//
|
||||
// Model B Rev 2.0
|
||||
//
|
||||
{
|
||||
.hwver = 0x04,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B",
|
||||
},
|
||||
{
|
||||
.hwver = 0x05,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B",
|
||||
},
|
||||
{
|
||||
.hwver = 0x06,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B",
|
||||
},
|
||||
|
||||
//
|
||||
// Model A
|
||||
//
|
||||
{
|
||||
.hwver = 0x07,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model A",
|
||||
},
|
||||
{
|
||||
.hwver = 0x08,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model A",
|
||||
},
|
||||
{
|
||||
.hwver = 0x09,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model A",
|
||||
},
|
||||
|
||||
//
|
||||
// Model B
|
||||
//
|
||||
{
|
||||
.hwver = 0x0d,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B",
|
||||
},
|
||||
{
|
||||
.hwver = 0x0e,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B",
|
||||
},
|
||||
{
|
||||
.hwver = 0x0f,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B",
|
||||
},
|
||||
|
||||
//
|
||||
// Model B+
|
||||
//
|
||||
{
|
||||
.hwver = 0x10,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B+",
|
||||
},
|
||||
{
|
||||
.hwver = 0x13,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B+",
|
||||
},
|
||||
{
|
||||
.hwver = 0x900032,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model B+",
|
||||
},
|
||||
|
||||
//
|
||||
// Compute Module
|
||||
//
|
||||
{
|
||||
.hwver = 0x11,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Compute Module 1",
|
||||
},
|
||||
{
|
||||
.hwver = 0x14,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Compute Module 1",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa020a0,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 3/L3",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa02100,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 3+",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa220a0,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Compute Module 3 Rev 1.0",
|
||||
},
|
||||
|
||||
//
|
||||
// Pi Zero
|
||||
//
|
||||
{
|
||||
.hwver = 0x900092,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Pi Zero v1.2",
|
||||
},
|
||||
{
|
||||
.hwver = 0x900093,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Pi Zero v1.3",
|
||||
},
|
||||
{
|
||||
.hwver = 0x920093,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Pi Zero v1.3",
|
||||
},
|
||||
{
|
||||
.hwver = 0x9200c1,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Pi Zero W v1.1",
|
||||
},
|
||||
{
|
||||
.hwver = 0x9000c1,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Pi Zero W v1.1",
|
||||
},
|
||||
|
||||
//
|
||||
// Model Zero 2 W
|
||||
//
|
||||
{
|
||||
.hwver = 0x902120,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi Zero 2 W v1.0",
|
||||
},
|
||||
|
||||
//
|
||||
// Model A+
|
||||
//
|
||||
{
|
||||
.hwver = 0x12,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model A+",
|
||||
},
|
||||
{
|
||||
.hwver = 0x15,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model A+",
|
||||
},
|
||||
{
|
||||
.hwver = 0x900021,
|
||||
.type = RPI_HWVER_TYPE_PI1,
|
||||
.periph_base = PERIPH_BASE_RPI,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI,
|
||||
.desc = "Model A+",
|
||||
},
|
||||
|
||||
//
|
||||
// Pi 2 Model B
|
||||
//
|
||||
{
|
||||
.hwver = 0xa01041,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 2",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa01040,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 2",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa21041,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 2",
|
||||
},
|
||||
//
|
||||
// Pi 2 with BCM2837
|
||||
//
|
||||
{
|
||||
.hwver = 0xa22042,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 2",
|
||||
},
|
||||
//
|
||||
// Pi 3 Model B
|
||||
//
|
||||
{
|
||||
.hwver = 0xa020d4,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 3 B+",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa020d3,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 3 B+",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa32082,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 3 B",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa02082,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 3",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa02083,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 3",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa22082,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 3",
|
||||
},
|
||||
{
|
||||
.hwver = 0xa22083,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Pi 3",
|
||||
},
|
||||
{
|
||||
.hwver = 0x9020e0,
|
||||
.type = RPI_HWVER_TYPE_PI2,
|
||||
.periph_base = PERIPH_BASE_RPI2,
|
||||
.videocore_base = VIDEOCORE_BASE_RPI2,
|
||||
.desc = "Model 3 A+",
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const rpi_hw_t *rpi_hw_detect(void)
|
||||
{
|
||||
const rpi_hw_t *result = NULL;
|
||||
uint32_t rev;
|
||||
unsigned i;
|
||||
|
||||
#ifdef __aarch64__
|
||||
// On ARM64, read revision from /proc/device-tree as it is not shown in
|
||||
// /proc/cpuinfo
|
||||
FILE *f = fopen("/proc/device-tree/system/linux,revision", "r");
|
||||
if (!f)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
size_t read = fread(&rev, 1, sizeof(uint32_t), f);
|
||||
if (read != sizeof(uint32_t))
|
||||
goto done;
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
rev = bswap_32(rev); // linux,revision appears to be in big endian
|
||||
#endif
|
||||
|
||||
for (i = 0; i < (sizeof(rpi_hw_info) / sizeof(rpi_hw_info[0])); i++)
|
||||
{
|
||||
uint32_t hwver = rpi_hw_info[i].hwver;
|
||||
if (rev == hwver)
|
||||
{
|
||||
result = &rpi_hw_info[i];
|
||||
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
#else
|
||||
FILE *f = fopen("/proc/cpuinfo", "r");
|
||||
char line[LINE_WIDTH_MAX];
|
||||
|
||||
if (!f)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (fgets(line, LINE_WIDTH_MAX - 1, f))
|
||||
{
|
||||
if (strstr(line, HW_VER_STRING))
|
||||
{
|
||||
char *substr;
|
||||
|
||||
substr = strstr(line, ": ");
|
||||
if (!substr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
rev = strtoul(&substr[1], NULL, 16); // Base 16
|
||||
if (errno)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < (sizeof(rpi_hw_info) / sizeof(rpi_hw_info[0])); i++)
|
||||
{
|
||||
uint32_t hwver = rpi_hw_info[i].hwver;
|
||||
|
||||
// Take out warranty and manufacturer bits
|
||||
hwver &= ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK);
|
||||
rev &= ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK);
|
||||
|
||||
if (rev == hwver)
|
||||
{
|
||||
result = &rpi_hw_info[i];
|
||||
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
done:
|
||||
fclose(f);
|
||||
|
||||
return result;
|
||||
}
|
||||
52
dependencies/rpi_ws281x/rpihw.h
vendored
Normal file
52
dependencies/rpi_ws281x/rpihw.h
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* rpihw.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 __RPIHW_H__
|
||||
#define __RPIHW_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t type;
|
||||
#define RPI_HWVER_TYPE_UNKNOWN 0
|
||||
#define RPI_HWVER_TYPE_PI1 1
|
||||
#define RPI_HWVER_TYPE_PI2 2
|
||||
#define RPI_HWVER_TYPE_PI4 3
|
||||
uint32_t hwver;
|
||||
uint32_t periph_base;
|
||||
uint32_t videocore_base;
|
||||
char *desc;
|
||||
} rpi_hw_t;
|
||||
|
||||
|
||||
const rpi_hw_t *rpi_hw_detect(void);
|
||||
|
||||
|
||||
#endif /* __RPIHW_H__ */
|
||||
10
dependencies/rpi_ws281x/version.h.in
vendored
Normal file
10
dependencies/rpi_ws281x/version.h.in
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/* Auto Generated Header built by version.py - DO NOT MODIFY */
|
||||
|
||||
#ifndef __@HEADERDEF@__
|
||||
#define __@HEADERDEF@__
|
||||
|
||||
#define VERSION_MAJOR @VERSION_MAJOR@
|
||||
#define VERSION_MINOR @VERSION_MINOR@
|
||||
#define VERSION_MICRO @VERSION_MICRO@
|
||||
|
||||
#endif /* __@HEADERDEF@__ */
|
||||
71
dependencies/rpi_ws281x/version.py
vendored
Normal file
71
dependencies/rpi_ws281x/version.py
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
#
|
||||
# SConstruct
|
||||
#
|
||||
# Copyright (c) 2016 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, os
|
||||
|
||||
def version_flags(env):
|
||||
if not env['V']:
|
||||
env['VERSIONCOMSTR'] = 'Version ${TARGET}'
|
||||
|
||||
def version_builders(env):
|
||||
def generate_version_header(target, source, env):
|
||||
headername = os.path.basename(target[0].abspath)
|
||||
headerdef = headername.replace('.', '_').replace('-', '_').upper()
|
||||
|
||||
try:
|
||||
version = open(source[0].abspath, 'r').readline().strip().split('.')
|
||||
except:
|
||||
version = [ '0', '0', '0' ]
|
||||
|
||||
f = open(headername, 'w')
|
||||
f.write('/* Auto Generated Header built by version.py - DO NOT MODIFY */\n')
|
||||
f.write('\n')
|
||||
f.write('#ifndef __%s__\n' % (headerdef))
|
||||
f.write('#define __%s__\n' % (headerdef))
|
||||
f.write('\n')
|
||||
f.write('#define VERSION_MAJOR %s\n' % version[0])
|
||||
f.write('#define VERSION_MINOR %s\n' % version[1])
|
||||
f.write('#define VERSION_MICRO %s\n' % version[2])
|
||||
f.write('\n')
|
||||
f.write('#endif /* __%s__ */\n' % (headerdef))
|
||||
f.close()
|
||||
|
||||
env.Append(BUILDERS = {
|
||||
'Version' : SCons.Builder.Builder(
|
||||
action = SCons.Action.Action(generate_version_header, '${VERSIONCOMSTR}'),
|
||||
suffix = '.h',
|
||||
),
|
||||
})
|
||||
|
||||
def exists(env):
|
||||
return 1
|
||||
|
||||
def generate(env, **kwargs):
|
||||
[f(env) for f in (version_flags, version_builders)]
|
||||
|
||||
|
||||
1326
dependencies/rpi_ws281x/ws2811.c
vendored
Normal file
1326
dependencies/rpi_ws281x/ws2811.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
133
dependencies/rpi_ws281x/ws2811.h
vendored
Normal file
133
dependencies/rpi_ws281x/ws2811.h
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* ws2811.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 __WS2811_H__
|
||||
#define __WS2811_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rpihw.h"
|
||||
#include "pwm.h"
|
||||
|
||||
|
||||
#define WS2811_TARGET_FREQ 800000 // Can go as low as 400000
|
||||
|
||||
// 4 color R, G, B and W ordering
|
||||
#define SK6812_STRIP_RGBW 0x18100800
|
||||
#define SK6812_STRIP_RBGW 0x18100008
|
||||
#define SK6812_STRIP_GRBW 0x18081000
|
||||
#define SK6812_STRIP_GBRW 0x18080010
|
||||
#define SK6812_STRIP_BRGW 0x18001008
|
||||
#define SK6812_STRIP_BGRW 0x18000810
|
||||
#define SK6812_SHIFT_WMASK 0xf0000000
|
||||
|
||||
// 3 color R, G and B ordering
|
||||
#define WS2811_STRIP_RGB 0x00100800
|
||||
#define WS2811_STRIP_RBG 0x00100008
|
||||
#define WS2811_STRIP_GRB 0x00081000
|
||||
#define WS2811_STRIP_GBR 0x00080010
|
||||
#define WS2811_STRIP_BRG 0x00001008
|
||||
#define WS2811_STRIP_BGR 0x00000810
|
||||
|
||||
// predefined fixed LED types
|
||||
#define WS2812_STRIP WS2811_STRIP_GRB
|
||||
#define SK6812_STRIP WS2811_STRIP_GRB
|
||||
#define SK6812W_STRIP SK6812_STRIP_GRBW
|
||||
|
||||
struct ws2811_device;
|
||||
|
||||
typedef uint32_t ws2811_led_t; //< 0xWWRRGGBB
|
||||
typedef struct ws2811_channel_t
|
||||
{
|
||||
int gpionum; //< GPIO Pin with PWM alternate function, 0 if unused
|
||||
int invert; //< Invert output signal
|
||||
int count; //< Number of LEDs, 0 if channel is unused
|
||||
int strip_type; //< Strip color layout -- one of WS2811_STRIP_xxx constants
|
||||
ws2811_led_t *leds; //< LED buffers, allocated by driver based on count
|
||||
uint8_t brightness; //< Brightness value between 0 and 255
|
||||
uint8_t wshift; //< White shift value
|
||||
uint8_t rshift; //< Red shift value
|
||||
uint8_t gshift; //< Green shift value
|
||||
uint8_t bshift; //< Blue shift value
|
||||
uint8_t *gamma; //< Gamma correction table
|
||||
} ws2811_channel_t;
|
||||
|
||||
typedef struct ws2811_t
|
||||
{
|
||||
uint64_t render_wait_time; //< time in µs before the next render can run
|
||||
struct ws2811_device *device; //< Private data for driver use
|
||||
const rpi_hw_t *rpi_hw; //< RPI Hardware Information
|
||||
uint32_t freq; //< Required output frequency
|
||||
int dmanum; //< DMA number _not_ already in use
|
||||
ws2811_channel_t channel[RPI_PWM_CHANNELS];
|
||||
} ws2811_t;
|
||||
|
||||
#define WS2811_RETURN_STATES(X) \
|
||||
X(0, WS2811_SUCCESS, "Success"), \
|
||||
X(-1, WS2811_ERROR_GENERIC, "Generic failure"), \
|
||||
X(-2, WS2811_ERROR_OUT_OF_MEMORY, "Out of memory"), \
|
||||
X(-3, WS2811_ERROR_HW_NOT_SUPPORTED, "Hardware revision is not supported"), \
|
||||
X(-4, WS2811_ERROR_MEM_LOCK, "Memory lock failed"), \
|
||||
X(-5, WS2811_ERROR_MMAP, "mmap() failed"), \
|
||||
X(-6, WS2811_ERROR_MAP_REGISTERS, "Unable to map registers into userspace"), \
|
||||
X(-7, WS2811_ERROR_GPIO_INIT, "Unable to initialize GPIO"), \
|
||||
X(-8, WS2811_ERROR_PWM_SETUP, "Unable to initialize PWM"), \
|
||||
X(-9, WS2811_ERROR_MAILBOX_DEVICE, "Failed to create mailbox device"), \
|
||||
X(-10, WS2811_ERROR_DMA, "DMA error"), \
|
||||
X(-11, WS2811_ERROR_ILLEGAL_GPIO, "Selected GPIO not possible"), \
|
||||
X(-12, WS2811_ERROR_PCM_SETUP, "Unable to initialize PCM"), \
|
||||
X(-13, WS2811_ERROR_SPI_SETUP, "Unable to initialize SPI"), \
|
||||
X(-14, WS2811_ERROR_SPI_TRANSFER, "SPI transfer error") \
|
||||
|
||||
#define WS2811_RETURN_STATES_ENUM(state, name, str) name = state
|
||||
#define WS2811_RETURN_STATES_STRING(state, name, str) str
|
||||
|
||||
typedef enum {
|
||||
WS2811_RETURN_STATES(WS2811_RETURN_STATES_ENUM),
|
||||
|
||||
WS2811_RETURN_STATE_COUNT
|
||||
} ws2811_return_t;
|
||||
|
||||
ws2811_return_t ws2811_init(ws2811_t *ws2811); //< Initialize buffers/hardware
|
||||
void ws2811_fini(ws2811_t *ws2811); //< Tear it all down
|
||||
ws2811_return_t ws2811_render(ws2811_t *ws2811); //< Send LEDs off to hardware
|
||||
ws2811_return_t ws2811_wait(ws2811_t *ws2811); //< Wait for DMA completion
|
||||
const char * ws2811_get_return_t_str(const ws2811_return_t state); //< Get string representation of the given return state
|
||||
void ws2811_set_custom_gamma_factor(ws2811_t *ws2811, double gamma_factor); //< Set a custom Gamma correction array based on a gamma correction factor
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WS2811_H__ */
|
||||
Reference in New Issue
Block a user