Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 73 additions & 16 deletions libsigrokdecode4DSL/decoders/rgb_led_ws281x/pd.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
##
## Copyright (C) 2016 Vladimir Ermakov <vooon341@gmail.com>
## Copyright (C) 2019 DreamSourceLab <support@dreamsourcelab.com>
## Copyright (C) 2021 Michael Miller <makuna@live.com>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
Expand All @@ -27,16 +28,22 @@ class SamplerateError(Exception):
class Decoder(srd.Decoder):
api_version = 3
id = 'rgb_led_ws281x'
name = 'RGB LED (WS281x)'
longname = 'RGB LED string decoder (WS281x)'
desc = 'RGB LED string protocol (WS281x).'
name = 'RGB LED WS2812+'
longname = 'RGB LED color decoder'
desc = 'Decodes colors from bus pulses for single wire RGB leds like APA106, WS2811, WS2812, WS2813, SK6812, TM1829, TM1814, and TX1812.'
license = 'gplv3+'
inputs = ['logic']
outputs = []
tags = ['Display', 'IC']
channels = (
{'id': 'din', 'name': 'DIN', 'desc': 'DIN data line'},
)
options = (
{'id': 'colors', 'desc': 'Colors', 'default': 'GRB',
'values': ( 'GRB', 'RGB', 'BRG', 'RBG', 'BGR', 'GRBW', 'RGBW', 'WRGB', 'LBGR', 'LGRB', 'LRGB', 'LRBG', 'LGBR', 'LBRG')},
{'id': 'polarity', 'desc': 'Polarity', 'default': 'normal',
'values': ('normal', 'inverted')},
)
annotations = (
('bit', 'Bit'),
('reset', 'RESET'),
Expand All @@ -58,22 +65,67 @@ def reset(self):
self.es = None
self.bits = []
self.bit_ = None
self.colorsize = None

def start(self):
self.out_ann = self.register(srd.OUTPUT_ANN)


def metadata(self, key, value):
if key == srd.SRD_CONF_SAMPLERATE:
self.samplerate = value

def handle_bits(self, samplenum):
if len(self.bits) == 24:
grb = reduce(lambda a, b: (a << 1) | b, self.bits)
rgb = (grb & 0xff0000) >> 8 | (grb & 0x00ff00) << 8 | (grb & 0x0000ff)
self.put(self.ss_packet, samplenum, self.out_ann,
[2, ['#%06x' % rgb]])
self.bits = []
self.ss_packet = samplenum
if len(self.bits) == self.colorsize:
elems = reduce(lambda a, b: (a << 1) | b, self.bits)
if self.colorsize == 24:
if self.options['colors'] == 'GRB':
rgb = (elems & 0xff0000) >> 8 | (elems & 0x00ff00) << 8 | (elems & 0x0000ff)
elif self.options['colors'] == 'RGB':
rgb = elems
elif self.options['colors'] == 'BRG':
rgb = (elems & 0xff0000) >> 16 | (elems & 0x00ffff) << 8
elif self.options['colors'] == 'RBG':
rgb = (elems & 0xff0000) | (elems & 0x00ff00) >> 8 | (elems & 0x0000ff) << 8
elif self.options['colors'] == 'BGR':
rgb = (elems & 0xff0000) >> 16 | (elems & 0x00ff00) | (elems & 0x0000ff) << 16

self.put(self.ss_packet, samplenum, self.out_ann,
[2, ['RGB#%06x' % rgb]])
else:
if self.options['colors'] == 'GRBW':
rgb = (elems & 0xff000000) >> 16 | (elems & 0x00ff0000) | (elems & 0x0000ff00) >> 8
w = (elems & 0x000000ff)
elif self.options['colors'] == 'RGBW':
rgb = (elems & 0xffffff00) >> 8
w = (elems & 0x000000ff)
elif self.options['colors'] == 'WRGB':
rgb = (elems & 0x00ffffff)
w = (elems & 0xff000000) >> 32
elif self.options['colors'] == 'LBGR':
rgb = (elems & 0x0000ff00) | (elems & 0x00ff0000) >> 16 | (elems & 0x000000ff) << 16
w = (elems & 0xff000000) >> 32
elif self.options['colors'] == 'LGRB':
rgb = (elems & 0x000000ff) | (elems & 0x00ff0000) >> 8 | (elems & 0x0000ff00) << 8
w = (elems & 0xff000000) >> 32
elif self.options['colors'] == 'LRGB':
rgb = (elems & 0x00ffffff)
w = (elems & 0xff000000) >> 32
elif self.options['colors'] == 'LRBG':
rgb = (elems & 0x00ff0000) | (elems & 0x0000ff00) >> 8 | (elems & 0x000000ff) << 8
w = (elems & 0xff000000) >> 32
elif self.options['colors'] == 'LGBR':
rgb = (elems & 0x00ffff00) >> 8 | (elems & 0x000000ff) << 16
w = (elems & 0xff000000) >> 32
elif self.options['colors'] == 'LBRG':
rgb = (elems & 0x00ff0000) >> 16 | (elems & 0x0000ffff) << 8
w = (elems & 0xff000000) >> 32

self.put(self.ss_packet, samplenum, self.out_ann,
[2, ['RGB#%06x #%02x' % (rgb, w)]])

self.bits = []
self.ss_packet = samplenum

def check_bit_(self, samplenum):
period = samplenum - self.ss
Expand All @@ -90,30 +142,35 @@ def decode(self):
if not self.samplerate:
raise SamplerateError('Cannot decode without samplerate.')

if len(self.options['colors']) == 4:
self.colorsize = 32
else:
self.colorsize = 24

while True:
if self.state == 'FIND RESET':
self.wait({0: 'l'})
self.wait({0: 'l' if self.options['polarity'] == 'normal' else 'h'})
self.ss = self.samplenum
self.wait({0: 'r'})
self.wait({0: 'e'})
self.es = self.samplenum
if ((self.es - self.ss) / self.samplerate > 50e-6):
self.state = 'RESET'
elif ((self.es - self.ss) / self.samplerate > 3e-6):
self.bits = []
self.ss = self.samplenum
self.ss_packet = self.samplenum
self.wait({0: 'f'})
self.wait({0: 'e'})
self.state = 'BIT FALLING'
elif self.state == 'RESET':
self.put(self.ss, self.es, self.out_ann, [1, ['RESET', 'RST', 'R']])
self.bits = []
self.ss = self.samplenum
self.ss_packet = self.samplenum
self.wait({0: 'f'})
self.wait({0: 'e'})
self.state = 'BIT FALLING'
elif self.state == 'BIT FALLING':
self.es = self.samplenum
self.wait({0: 'r'})
self.wait({0: 'e'})
if ((self.samplenum - self.es) / self.samplerate > 50e-6):
self.check_bit_(self.samplenum)
self.put(self.ss, self.es, self.out_ann,
Expand All @@ -134,5 +191,5 @@ def decode(self):
self.handle_bits(self.samplenum)

self.ss = self.samplenum
self.wait({0: 'f'})
self.wait({0: 'e'})
self.state = 'BIT FALLING'