代码拉取完成,页面将自动刷新
/*
* LedDriver.c
*
* Created on: 13.04.2011
* Author: Mike Shatohin (brunql)
* Project: Lightpack
*
* Lightpack is a content-appropriate ambient lighting system for any computer
*
* Copyright (c) 2011 Mike Shatohin, mikeshatohin [at] gmail.com
*
* Lightpack is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Lightpack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <avr/io.h>
#include "iodefs.h"
#include "Lightpack.h"
#include "LedDriver.h"
#include "version.h"
#if (LIGHTPACK_HW >= 6)
/*
* Hardware 6.x
*/
#define LATCH_PIN (B, 0)
#define SCK_PIN (B, 1)
#define MOSI_PIN (B, 2)
static const uint8_t LedsNumberForOneDriver = 5;
static inline void _SPI_Write12(uint16_t byte)
{
CLR(MOSI_PIN);
// 12-bits
for (uint16_t bit = 0x0800; bit != 0; bit >>= 1)
{
if (byte & bit)
{
SET(MOSI_PIN);
} else {
CLR(MOSI_PIN);
}
SET(SCK_PIN);
CLR(SCK_PIN);
}
}
static inline void _LedDriver_LatchPulse(void)
{
SET(LATCH_PIN);
CLR(LATCH_PIN);
}
void LedDriver_Init(void)
{
OUTPUT(SCK_PIN);
OUTPUT(MOSI_PIN);
OUTPUT(LATCH_PIN);
CLR(LATCH_PIN);
CLR(SCK_PIN);
CLR(MOSI_PIN);
LedDriver_OffLeds();
}
void LedDriver_Update(const RGB_t imageFrame[LEDS_COUNT])
{
// ...
// LedDriver2
// 10 9 8 7 6
// 0 B G R B G R B G R B G R B G R
// LedDriver1
// 5 4 3 2 1
// 0 B G R B G R B G R B G R B G R
_SPI_Write12(0);
for (uint8_t i = LedsNumberForOneDriver; i < LEDS_COUNT; i++)
{
_SPI_Write12(imageFrame[i].b);
_SPI_Write12(imageFrame[i].g);
_SPI_Write12(imageFrame[i].r);
}
_SPI_Write12(0);
for (uint8_t i = 0; i < LedsNumberForOneDriver; i++)
{
_SPI_Write12(imageFrame[i].b);
_SPI_Write12(imageFrame[i].g);
_SPI_Write12(imageFrame[i].r);
}
_LedDriver_LatchPulse();
}
void LedDriver_OffLeds(void)
{
for (uint8_t i = 0; i < 16; i++)
_SPI_Write12(0x0000);
_LedDriver_LatchPulse();
}
#elif (LIGHTPACK_HW == 5)
/*
* Hardware 5.x
*/
#define LATCH_PIN (B, 0)
#define SCK_PIN (B, 1)
#define MOSI_PIN (B, 2)
static const uint8_t LedsNumberForOneDriver = 5;
static inline void _SPI_Write8(const uint8_t byte)
{
SPDR = byte;
while ((SPSR & (1 << SPIF)) == false) { }
}
static inline void _SPI_Write16(const uint16_t word)
{
_SPI_Write8((word >> 8) & 0xff);
_SPI_Write8(word & 0xff);
}
static inline void _LedDriver_LatchPulse(void)
{
SET(LATCH_PIN);
CLR(LATCH_PIN);
}
static inline void _LedDriver_UpdateLedsPWM(
const uint8_t startIndex, const uint8_t endIndex,
const RGB_t imageFrame[LEDS_COUNT],
const uint8_t pwmIndex )
{
uint16_t sendme = 0x0000;
uint16_t bit = 1;
for (uint8_t i = startIndex; i < endIndex; i++)
{
if (imageFrame[i].r > pwmIndex)
sendme |= bit;
bit <<= 1;
if (imageFrame[i].g > pwmIndex)
sendme |= bit;
bit <<= 1;
if (imageFrame[i].b > pwmIndex)
sendme |= bit;
bit <<= 1;
}
_SPI_Write16(sendme);
}
void LedDriver_Init(void)
{
OUTPUT(SCK_PIN);
OUTPUT(MOSI_PIN);
OUTPUT(LATCH_PIN);
CLR(LATCH_PIN);
// Setup SPI Master with max SPI clock speed (F_CPU / 2)
SPSR = (1 << SPI2X);
SPCR = (1 << SPE) | (1 << MSTR);
LedDriver_OffLeds();
}
void LedDriver_UpdatePWM(const RGB_t imageFrame[LEDS_COUNT], const uint8_t pwmIndex)
{
// ...
// LedDriver2
// 10 9 8 7 6
// 0 B G R B G R B G R B G R B G R
// LedDriver1
// 5 4 3 2 1
// 0 B G R B G R B G R B G R B G R
// for (int8_t i = LEDS_COUNT - LedsNumberForOneDriver; i >= 0; i -= LedsNumberForOneDriver)
// {
// _LedDriver_UpdateLeds(i, i + LedsNumberForOneDriver,
// LevelsForPWM, pwmIndex);
// }
_LedDriver_UpdateLedsPWM(LedsNumberForOneDriver, LEDS_COUNT, imageFrame, pwmIndex);
_LedDriver_UpdateLedsPWM(0, LedsNumberForOneDriver, imageFrame, pwmIndex);
_LedDriver_LatchPulse();
}
void LedDriver_OffLeds(void)
{
_SPI_Write16(0x0000);
_SPI_Write16(0x0000);
_LedDriver_LatchPulse();
}
#elif (LIGHTPACK_HW == 4)
/*
* Hardware 4.x
*/
#define LATCH_1 (B, 4)
#define CLK_1 (B, 5)
#define DATA_1 (B, 6)
#define LATCH_2 (B, 0)
#define CLK_2 (B, 1)
#define DATA_2 (B, 2)
enum LEDS { LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8 };
static inline void _LedDrivers_LatchPulse(void)
{
SET(LATCH_1);
SET(LATCH_2);
CLR(LATCH_1);
CLR(LATCH_2);
}
static inline void _LedDrivers_ClkUp(void)
{
SET(CLK_1);
SET(CLK_2);
}
static inline void _LedDrivers_ClkDown(void)
{
CLR(CLK_1);
CLR(CLK_2);
}
// Parallel serial output of the one led for each driver, Pulse Width Modulation
static inline void _LedDrivers_PSO_PWM(
const RGB_t imageFrame[LEDS_COUNT],
const uint8_t pwmIndex,
const uint8_t ledIndex1,
const uint8_t ledIndex2 )
{
// LedDriver connection: NC B G R
_LedDrivers_ClkDown();
CLR(DATA_1);
CLR(DATA_2);
_LedDrivers_ClkUp();
_LedDrivers_ClkDown();
if (imageFrame[ledIndex1].b > pwmIndex) SET(DATA_1) else CLR(DATA_1);
if (imageFrame[ledIndex2].b > pwmIndex) SET(DATA_2) else CLR(DATA_2);
_LedDrivers_ClkUp();
_LedDrivers_ClkDown();
if (imageFrame[ledIndex1].g > pwmIndex) SET(DATA_1) else CLR(DATA_1);
if (imageFrame[ledIndex2].g > pwmIndex) SET(DATA_2) else CLR(DATA_2);
_LedDrivers_ClkUp();
_LedDrivers_ClkDown();
if (imageFrame[ledIndex1].r > pwmIndex) SET(DATA_1) else CLR(DATA_1);
if (imageFrame[ledIndex2].r > pwmIndex) SET(DATA_2) else CLR(DATA_2);
_LedDrivers_ClkUp();
}
void LedDriver_Init(void)
{
CLR(CLK_1);
CLR(CLK_2);
CLR(LATCH_1);
CLR(LATCH_2);
CLR(DATA_1);
CLR(DATA_2);
OUTPUT(CLK_1);
OUTPUT(CLK_2);
OUTPUT(LATCH_1);
OUTPUT(LATCH_2);
OUTPUT(DATA_1);
OUTPUT(DATA_2);
}
void LedDriver_UpdatePWM(const RGB_t imageFrame[LEDS_COUNT], const uint8_t pwmIndex)
{
_LedDrivers_PSO_PWM(imageFrame, pwmIndex, LED4, LED8);
_LedDrivers_PSO_PWM(imageFrame, pwmIndex, LED3, LED7);
_LedDrivers_PSO_PWM(imageFrame, pwmIndex, LED2, LED6);
_LedDrivers_PSO_PWM(imageFrame, pwmIndex, LED1, LED5);
_LedDrivers_LatchPulse();
}
void LedDriver_OffLeds(void)
{
CLR(DATA_1);
CLR(DATA_2);
for (uint8_t i = 0; i < 16; i++)
{
_LedDrivers_ClkDown();
_LedDrivers_ClkUp();
}
_LedDrivers_LatchPulse();
}
#else
# error "LIGHTPACK_HW must be passed thru command line as major number of the hardware revision"
#endif /* (LIGHTPACK_HW switch) */
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。