Cleanup, reorganization
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
#include <avr/io.h>
|
||||
#include <util/delay_basic.h>
|
||||
#include <stdint.h>
|
||||
#include "ws_driver.h"
|
||||
|
||||
/** Raise the bus line */
|
||||
#define ws_high() (WS_PORT) |= (1 << WS_BIT)
|
||||
|
||||
/** Drop the bus line */
|
||||
#define ws_low() (WS_PORT) &= ~(1 << WS_BIT)
|
||||
|
||||
/* Convert nanoseconds to cycle count */
|
||||
#define ns2cycles(ns) ( (ns) / (1000000000L / (signed long) F_CPU) )
|
||||
|
||||
/** Wait c cycles */
|
||||
#define delay_c(c) (((c) > 0) ? __builtin_avr_delay_cycles(c) : __builtin_avr_delay_cycles(0))
|
||||
|
||||
/** Wait n nanoseconds, plus c cycles */
|
||||
#define delay_ns_c(ns, c) delay_c(ns2cycles(ns) + (c))
|
||||
|
||||
|
||||
/** Latch and display the RGB values */
|
||||
void ws_show()
|
||||
{
|
||||
ws_low();
|
||||
delay_ns_c(WS_T_LATCH, 0);
|
||||
}
|
||||
|
||||
|
||||
/** Send one byte to the RGB strip */
|
||||
void ws_send_byte(uint8_t bb)
|
||||
{
|
||||
for (int8_t i = 7; i >= 0; --i) {
|
||||
if (bb & (1 << i)) {
|
||||
// send ONE
|
||||
ws_high();
|
||||
delay_ns_c(WS_T_1H, -2);
|
||||
ws_low();
|
||||
delay_ns_c(WS_T_1L, -10); // compensation for overhead
|
||||
} else {
|
||||
// send ZERO
|
||||
ws_high();
|
||||
delay_ns_c(WS_T_0H, -2);
|
||||
ws_low();
|
||||
delay_ns_c(WS_T_0L, -10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Send RGB color to the strip */
|
||||
void ws_send_rgb(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
int8_t i;
|
||||
|
||||
// manualy inlined, because `inline` doesn't work with delays.
|
||||
|
||||
// GREEN
|
||||
for (i = 7; i >= 0; --i) {
|
||||
if (g & (1 << i)) {
|
||||
// send ONE
|
||||
ws_high();
|
||||
delay_ns_c(WS_T_1H, -2);
|
||||
ws_low();
|
||||
delay_ns_c(WS_T_1L, -10);
|
||||
} else {
|
||||
// send ZERO
|
||||
ws_high();
|
||||
delay_ns_c(WS_T_0H, -2);
|
||||
ws_low();
|
||||
delay_ns_c(WS_T_0L, -10);
|
||||
}
|
||||
}
|
||||
|
||||
// RED
|
||||
for (i = 7; i >= 0; --i) {
|
||||
if (r & (1 << i)) {
|
||||
// send ONE
|
||||
ws_high();
|
||||
delay_ns_c(WS_T_1H, -2);
|
||||
ws_low();
|
||||
delay_ns_c(WS_T_1L, -10);
|
||||
} else {
|
||||
// send ZERO
|
||||
ws_high();
|
||||
delay_ns_c(WS_T_0H, -2);
|
||||
ws_low();
|
||||
delay_ns_c(WS_T_0L, -10);
|
||||
}
|
||||
}
|
||||
|
||||
// BLUE
|
||||
for (i = 7; i >= 0; --i) {
|
||||
if (b & (1 << i)) {
|
||||
// send ONE
|
||||
ws_high();
|
||||
delay_ns_c(WS_T_1H, -2);
|
||||
ws_low();
|
||||
delay_ns_c(WS_T_1L, -10);
|
||||
} else {
|
||||
// send ZERO
|
||||
ws_high();
|
||||
delay_ns_c(WS_T_0H, -2);
|
||||
ws_low();
|
||||
delay_ns_c(WS_T_0L, -10);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
// -- AVR GCC utility for driving WS2812B and similar RGB LED stripes --
|
||||
|
||||
// You must define the following in config file or here:
|
||||
// * WS_PORT
|
||||
// * WS_BIT
|
||||
|
||||
#include "config.h"
|
||||
|
||||
// The pin must be set to OUTPUT before using the output functions
|
||||
|
||||
|
||||
// --- timing constraints (NS) ---
|
||||
|
||||
#ifndef WS_T_1H
|
||||
#define WS_T_1H 700
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_1L
|
||||
#define WS_T_1L 150
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_0H
|
||||
#define WS_T_0H 150
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_0L
|
||||
#define WS_T_0L 700
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_LATCH
|
||||
#define WS_T_LATCH 7000
|
||||
#endif
|
||||
|
||||
|
||||
// More precise timing
|
||||
// #define WS_T_1H 800
|
||||
// #define WS_T_1L 450
|
||||
// #define WS_T_0H 200
|
||||
// #define WS_T_0L 650
|
||||
// #define WS_T_LATCH 50000
|
||||
|
||||
|
||||
/** Latch and display the RGB values */
|
||||
void ws_show(void);
|
||||
|
||||
|
||||
/** Send one byte to the RGB strip */
|
||||
void ws_send_byte(uint8_t b);
|
||||
|
||||
|
||||
/** Send RGB color to the strip */
|
||||
void ws_send_rgb(uint8_t r, uint8_t g, uint8_t b);
|
||||
@@ -0,0 +1,97 @@
|
||||
#include <avr/io.h>
|
||||
#include <util/delay_basic.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "extra_delays.h"
|
||||
#include "pins.h"
|
||||
#include "ws_driver2.h"
|
||||
|
||||
|
||||
|
||||
/** Latch and display the RGB values */
|
||||
void ws_show_real(PORT_P portp, BIT_N pin)
|
||||
{
|
||||
cbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_LATCH, 0);
|
||||
}
|
||||
|
||||
|
||||
/** Send one byte to the RGB strip */
|
||||
void ws_send_byte_real(PORT_P portp, BIT_N pin, uint8_t bb)
|
||||
{
|
||||
for (int8_t i = 7; i >= 0; --i) {
|
||||
if (bb & (1 << i)) {
|
||||
// send ONE
|
||||
sbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_1H, -2);
|
||||
cbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_1L, -10); // compensation for overhead
|
||||
} else {
|
||||
// send ZERO
|
||||
sbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_0H, -2);
|
||||
cbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_0L, -10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Send RGB color to the strip */
|
||||
void ws_send_rgb_real(PORT_P portp, BIT_N pin, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
int8_t i;
|
||||
|
||||
// manualy inlined, because `inline` doesn't work with delays.
|
||||
|
||||
// GREEN
|
||||
for (i = 7; i >= 0; --i) {
|
||||
if (g & (1 << i)) {
|
||||
// send ONE
|
||||
sbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_1H, -2);
|
||||
cbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_1L, -10);
|
||||
} else {
|
||||
// send ZERO
|
||||
sbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_0H, -2);
|
||||
cbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_0L, -10);
|
||||
}
|
||||
}
|
||||
|
||||
// RED
|
||||
for (i = 7; i >= 0; --i) {
|
||||
if (r & (1 << i)) {
|
||||
// send ONE
|
||||
sbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_1H, -2);
|
||||
cbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_1L, -10);
|
||||
} else {
|
||||
// send ZERO
|
||||
sbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_0H, -2);
|
||||
cbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_0L, -10);
|
||||
}
|
||||
}
|
||||
|
||||
// BLUE
|
||||
for (i = 7; i >= 0; --i) {
|
||||
if (b & (1 << i)) {
|
||||
// send ONE
|
||||
sbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_1H, -2);
|
||||
cbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_1L, -10);
|
||||
} else {
|
||||
// send ZERO
|
||||
sbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_0H, -2);
|
||||
cbi_p(portp, pin);
|
||||
delay_ns_c(WS_T_0L, -10);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "pins.h"
|
||||
|
||||
// -- Utility for driving WS2812B and similar RGB LED stripes --
|
||||
|
||||
// --- timing constraints (NS) ---
|
||||
|
||||
#ifndef WS_T_1H
|
||||
#define WS_T_1H 700
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_1L
|
||||
#define WS_T_1L 150
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_0H
|
||||
#define WS_T_0H 150
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_0L
|
||||
#define WS_T_0L 700
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_LATCH
|
||||
#define WS_T_LATCH 6000
|
||||
#endif
|
||||
|
||||
|
||||
// More precise timing
|
||||
// #define WS_T_1H 800
|
||||
// #define WS_T_1L 450
|
||||
// #define WS_T_0H 200
|
||||
// #define WS_T_0L 650
|
||||
// #define WS_T_LATCH 50000
|
||||
|
||||
|
||||
// Only ws_show / ws_send_byte / ws_send_rgb should be used, with port alias macros
|
||||
// See pins.h for reference
|
||||
|
||||
/** Latch and display the RGB values */
|
||||
void ws_show_real(PORT_P port, BIT_N pin);
|
||||
#define ws_show_aux(port, pin) ws_show_real(®_port(port), pin)
|
||||
#define ws_show(io) ws_show_aux(io)
|
||||
|
||||
|
||||
/** Send one byte to the RGB strip */
|
||||
void ws_send_byte_real(PORT_P port, BIT_N pin, uint8_t b);
|
||||
#define ws_send_byte_aux(port, pin, b) ws_send_byte_real(®_port(port), pin, b)
|
||||
#define ws_send_byte(io, b) ws_send_byte_aux(io, b)
|
||||
|
||||
|
||||
/** Send RGB color to the strip */
|
||||
void ws_send_rgb_real(PORT_P port, BIT_N pin, uint8_t r, uint8_t g, uint8_t b);
|
||||
#define ws_send_rgb_aux(port, pin, r, g, b) ws_send_rgb_real(®_port(port), pin, r, g, b)
|
||||
#define ws_send_rgb(io, r, g, b) ws_send_rgb_aux(io, r, g, b)
|
||||
@@ -0,0 +1,75 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/sfr_defs.h>
|
||||
#include <util/delay_basic.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ws_driver3.h"
|
||||
|
||||
#define WS_PORT PORTB
|
||||
#define WS_BIT 0
|
||||
|
||||
uint16_t ws_port = _SFR_ADDR(PORTB);
|
||||
uint8_t ws_bit;
|
||||
|
||||
/** Raise the bus line *///_SFR_MEM8(ws_port)
|
||||
#define ws_high() do { _SFR_MEM8(ws_port) |= (1 << 0); } while(0)
|
||||
//#define ws_high() (_SFR_MEM8(_SFR_ADDR(PORTB))) |= (1 << WS_BIT)
|
||||
|
||||
/** Drop the bus line */
|
||||
#define ws_low() do { _SFR_MEM8(ws_port) &= ~(1 << 0); } while(0)
|
||||
//#define ws_low() (_SFR_MEM8(_SFR_ADDR(PORTB))) &= ~(1 << WS_BIT)
|
||||
|
||||
/* Convert nanoseconds to cycle count */
|
||||
#define ns2cycles(ns) ( (ns) / (1000000000L / (signed long) F_CPU) )
|
||||
|
||||
/** Wait c cycles */
|
||||
#define delay_c(c) (((c) > 0) ? __builtin_avr_delay_cycles(c) : __builtin_avr_delay_cycles(0))
|
||||
|
||||
/** Wait n nanoseconds, plus c cycles */
|
||||
#define delay_ns_c(ns, c) delay_c(ns2cycles(ns) + (c))
|
||||
|
||||
|
||||
void ws_bind(uint8_t port_addr, uint8_t bit)
|
||||
{
|
||||
// ws_port = port_addr;
|
||||
// ws_bit = bit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Latch and display the RGB values */
|
||||
void ws_show()
|
||||
{
|
||||
ws_low();
|
||||
delay_ns_c(WS_T_LATCH, 0);
|
||||
}
|
||||
|
||||
#define _do_ws_send_byte(x) do { \
|
||||
for (int8_t i = 7; i >= 0; --i) { \
|
||||
if (x & (1 << i)) { \
|
||||
ws_high(); \
|
||||
delay_ns_c(WS_T_1H, -2); \
|
||||
ws_low(); \
|
||||
delay_ns_c(WS_T_1L, -10); \
|
||||
} else { \
|
||||
ws_high(); \
|
||||
delay_ns_c(WS_T_0H, -2); \
|
||||
ws_low(); \
|
||||
delay_ns_c(WS_T_0L, -10); \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
void ws_send_byte(uint8_t b)
|
||||
{
|
||||
_do_ws_send_byte(b);
|
||||
}
|
||||
|
||||
|
||||
/** Send RGB color to the strip */
|
||||
void ws_send_rgb(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
_do_ws_send_byte(g);
|
||||
_do_ws_send_byte(r);
|
||||
_do_ws_send_byte(b);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
// -- AVR GCC utility for driving WS2812B and similar RGB LED stripes --
|
||||
|
||||
// You must define the following in config file or here:
|
||||
|
||||
// The pin must be set to OUTPUT before using the output functions
|
||||
|
||||
|
||||
// --- timing constraints (NS) ---
|
||||
|
||||
#ifndef WS_T_1H
|
||||
#define WS_T_1H 700
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_1L
|
||||
#define WS_T_1L 150
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_0H
|
||||
#define WS_T_0H 150
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_0L
|
||||
#define WS_T_0L 700
|
||||
#endif
|
||||
|
||||
#ifndef WS_T_LATCH
|
||||
#define WS_T_LATCH 7000
|
||||
#endif
|
||||
|
||||
|
||||
// More precise timing
|
||||
// #define WS_T_1H 800
|
||||
// #define WS_T_1L 450
|
||||
// #define WS_T_0H 200
|
||||
// #define WS_T_0L 650
|
||||
// #define WS_T_LATCH 50000
|
||||
|
||||
|
||||
|
||||
void ws_bind(uint8_t port_addr, uint8_t bit);
|
||||
|
||||
|
||||
/** Latch and display the RGB values */
|
||||
void ws_show(void);
|
||||
|
||||
|
||||
/** Send one byte to the RGB strip */
|
||||
void ws_send_byte(uint8_t b);
|
||||
|
||||
|
||||
/** Send RGB color to the strip */
|
||||
void ws_send_rgb(uint8_t r, uint8_t g, uint8_t b);
|
||||
Reference in New Issue
Block a user