Added grove-led-bar my9221 driver
This commit is contained in:
parent
aaf4769c11
commit
a53afd377c
1 changed files with 84 additions and 0 deletions
84
grove-led-bar/my9221.py
Normal file
84
grove-led-bar/my9221.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
"""
|
||||
Circuitpython MY9221 LED driver
|
||||
|
||||
MIT License
|
||||
Copyright (c) 2018 Mike Causer
|
||||
Copyright (c) 2025 P.M. Kuipers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
from digitalio import DigitalInOut, Direction
|
||||
from microcontroller import delay_us
|
||||
|
||||
class MY9221:
|
||||
def __init__(self, di, dcki, reverse=False):
|
||||
self._d = DigitalInOut(di)
|
||||
self._c = DigitalInOut(dcki)
|
||||
self._r = reverse
|
||||
self._d.direction = Direction.OUTPUT
|
||||
self._d.value = 0
|
||||
self._c.direction = Direction.OUTPUT
|
||||
self._c.value = 0
|
||||
|
||||
def _latch(self):
|
||||
self._d.value = 0
|
||||
delay_us(10000)
|
||||
for i in range(4):
|
||||
self._d.value = 1
|
||||
self._d.value = 0
|
||||
delay_us(10000)
|
||||
|
||||
def _write16(self, data):
|
||||
for i in range(15,-1,-1):
|
||||
self._d.value = ((data >> i) & 1) # shift next bit
|
||||
self._c.value = not self._c.value # trigger clock (triggers on both rising and falling edges)
|
||||
|
||||
def _begin(self):
|
||||
self._write16(0x0000) # command: 8bit mode
|
||||
|
||||
def _end(self):
|
||||
# unused last 2 channels are required to fill the 208 bit shift register
|
||||
self._write16(0)
|
||||
self._write16(0)
|
||||
self._latch()
|
||||
|
||||
def reverse(self, val=None):
|
||||
if val is None:
|
||||
return self._r
|
||||
self._r = val
|
||||
|
||||
def level(self, val, brightness=255):
|
||||
self._begin()
|
||||
for i in range(9,-1,-1) if self._r else range(10):
|
||||
self._write16(brightness if val > i else 0)
|
||||
self._end()
|
||||
|
||||
def bits(self, val, brightness=255):
|
||||
val &= 0x3FF
|
||||
self._begin()
|
||||
for i in range(9,-1,-1) if self._r else range(10):
|
||||
self._write16(brightness if (val >> i) & 1 else 0)
|
||||
self._end()
|
||||
|
||||
def bytes(self, buf):
|
||||
self._begin()
|
||||
for i in range(9,-1,-1) if self._r else range(10):
|
||||
self._write16(buf[i])
|
||||
self._end()
|
Loading…
Reference in a new issue