82 lines
1.8 KiB
C++
82 lines
1.8 KiB
C++
#pragma once
|
|
#include <util/delay.h>
|
|
|
|
template <int BITS> class ShiftReg
|
|
{
|
|
private:
|
|
static constexpr int BYTES = (BITS % 8 == 0) ? (BITS/8) : (BITS/8+1);
|
|
|
|
static constexpr bool invert = true;
|
|
|
|
volatile unsigned char *_port;
|
|
const unsigned char _pinSer;
|
|
const unsigned char _pinSerClk;
|
|
const unsigned char _pinRClk;
|
|
|
|
unsigned char _lastData[BYTES] = {};
|
|
|
|
public:
|
|
|
|
ShiftReg(volatile unsigned char* const port, const unsigned char pinSer, const unsigned char pinSerClk,
|
|
const unsigned char pinRClk):
|
|
_port(port), _pinSer(pinSer), _pinSerClk(pinSerClk), _pinRClk(pinRClk)
|
|
{
|
|
clear();
|
|
}
|
|
void setBit(unsigned char bit, bool value)
|
|
{
|
|
if(BITS <= bit)
|
|
return;
|
|
bit = BITS - bit - 1;
|
|
if(value)
|
|
_lastData[bit/8] |= (1<<(bit%8));
|
|
else
|
|
_lastData[bit/8] &= ~(1<<(bit%8));
|
|
write(_lastData);
|
|
}
|
|
bool getBit(unsigned char bit)
|
|
{
|
|
if(BITS <= bit)
|
|
return false;
|
|
bit = BITS - bit - 1;
|
|
return _lastData[bit/8] & (1<<(bit%8));
|
|
}
|
|
void write(const unsigned char * const in)
|
|
{
|
|
for(unsigned char i = 0 ; i < BYTES; ++i)
|
|
_lastData[i] = in[i];
|
|
|
|
if constexpr(invert)
|
|
{
|
|
*_port |= ((1<<_pinSer) | (1<<_pinSerClk));
|
|
*_port |= (1<<_pinRClk);
|
|
|
|
for(unsigned char i = 0; i < BITS; ++i)
|
|
{
|
|
*_port |= (1 << _pinSerClk);
|
|
in[i/8] & (1<<(i%8)) ? (*_port &= ~(1 << _pinSer)) : (*_port |= (1 << _pinSer));
|
|
*_port &= ~(1 << _pinSerClk);
|
|
}
|
|
*_port &= ~(1<<_pinRClk);
|
|
}
|
|
else
|
|
{
|
|
*_port &= ~((1<<_pinSer) | (1<<_pinSerClk));
|
|
*_port &= ~(1<<_pinRClk);
|
|
for(unsigned char i = 0; i < BITS; ++i)
|
|
{
|
|
*_port &= ~(1 << _pinSerClk);
|
|
in[i/8] & (1<<(i%8)) ? (*_port |= (1 << _pinSer)) : (*_port &= ~(1 << _pinSer));
|
|
*_port |= (1 << _pinSerClk);
|
|
}
|
|
*_port |= 1<<_pinRClk;
|
|
}
|
|
}
|
|
void clear(bool value = false)
|
|
{
|
|
for(unsigned char i = 0 ; i < BYTES; ++i)
|
|
_lastData[i] = value ? 0xff : 0x00;
|
|
write(_lastData);
|
|
}
|
|
};
|