2013-08-28 16:30:00 -04:00
|
|
|
//
|
|
|
|
// FILE: FastShiftOut.cpp
|
|
|
|
// AUTHOR: Rob Tillaart
|
2015-03-06 09:37:48 -05:00
|
|
|
// VERSION: 0.1.04
|
2013-08-29 05:39:24 -04:00
|
|
|
// PURPOSE: shiftout that implements the Print interface
|
2013-09-29 06:38:05 -04:00
|
|
|
// DATE: 2013-08-22
|
2013-08-28 16:30:00 -04:00
|
|
|
// URL:
|
|
|
|
//
|
|
|
|
// Released to the public domain
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "FastShiftOut.h"
|
|
|
|
|
2013-08-29 05:39:24 -04:00
|
|
|
//
|
|
|
|
// Constructor
|
|
|
|
// prepares the digitalWrite()
|
2015-03-06 09:37:48 -05:00
|
|
|
FastShiftOut::FastShiftOut(const uint8_t datapin, const uint8_t clockpin, const uint8_t bitOrder)
|
2013-08-28 16:30:00 -04:00
|
|
|
{
|
|
|
|
_bitorder = bitOrder;
|
|
|
|
_value = -1;
|
2013-08-29 05:39:24 -04:00
|
|
|
pinMode(datapin, OUTPUT);
|
|
|
|
pinMode(clockpin, OUTPUT);
|
2015-03-06 09:37:48 -05:00
|
|
|
|
2013-08-29 05:39:24 -04:00
|
|
|
// uint8_t _datatimer = digitalPinToTimer(datapin);
|
|
|
|
// if (_datatimer != NOT_ON_TIMER) turnOffPWM(_datatimer); TODO
|
2015-03-06 09:37:48 -05:00
|
|
|
uint8_t _dataport = digitalPinToPort(datapin);
|
2013-08-28 16:30:00 -04:00
|
|
|
_dataout = portOutputRegister(_dataport);
|
2015-03-06 09:37:48 -05:00
|
|
|
_databit = digitalPinToBitMask(datapin);
|
|
|
|
|
2013-08-29 05:39:24 -04:00
|
|
|
// uint8_t _clocktimer = digitalPinToTimer(clockpin);
|
2013-08-28 16:30:00 -04:00
|
|
|
// if (_clocktimer != NOT_ON_TIMER) turnOffPWM(_clocktimer);
|
2015-03-06 09:37:48 -05:00
|
|
|
uint8_t _clockport = digitalPinToPort(clockpin);
|
2013-08-28 16:30:00 -04:00
|
|
|
_clockout = portOutputRegister(_clockport);
|
2015-03-06 09:37:48 -05:00
|
|
|
_clockbit = digitalPinToBitMask(clockpin);
|
2013-08-28 16:30:00 -04:00
|
|
|
}
|
|
|
|
|
2013-08-29 05:39:24 -04:00
|
|
|
//
|
|
|
|
// write() must implement the virtual write of Print class
|
|
|
|
//
|
2015-03-06 09:37:48 -05:00
|
|
|
// approx 64us/byte
|
|
|
|
size_t FastShiftOut::write(const uint8_t data)
|
2013-08-28 16:30:00 -04:00
|
|
|
{
|
|
|
|
_value = data;
|
2015-03-06 09:37:48 -05:00
|
|
|
for (uint8_t i = 0; i < 8; i++)
|
2013-08-28 16:30:00 -04:00
|
|
|
{
|
|
|
|
uint8_t v;
|
2015-03-06 09:37:48 -05:00
|
|
|
if (_bitorder == LSBFIRST) v = (_value & (1 << i));
|
|
|
|
else v = (_value & (1 << (7 - i)));
|
|
|
|
|
2013-08-28 16:30:00 -04:00
|
|
|
uint8_t oldSREG = SREG;
|
|
|
|
cli();
|
2015-03-06 09:37:48 -05:00
|
|
|
if (v == 0) *_dataout &= ~_databit;
|
|
|
|
else *_dataout |= _databit;
|
2013-08-28 16:30:00 -04:00
|
|
|
*_clockout |= _clockbit;
|
|
|
|
*_clockout &= ~_clockbit;
|
|
|
|
SREG = oldSREG;
|
|
|
|
}
|
2013-08-29 05:39:24 -04:00
|
|
|
return 1;
|
2013-08-28 16:30:00 -04:00
|
|
|
}
|
|
|
|
|
2015-03-06 09:37:48 -05:00
|
|
|
//
|
|
|
|
// this version is twice as fast,
|
|
|
|
// but it is in CLI() mode
|
|
|
|
// approx 32 us / byte
|
|
|
|
// size_t FastShiftOut::write(uint8_t data)
|
|
|
|
// {
|
|
|
|
// _value = data;
|
|
|
|
// // prep masks
|
|
|
|
// uint8_t dm1 = *_dataout | _databit;
|
|
|
|
// uint8_t dm0 = *_dataout & ~_databit;
|
|
|
|
// uint8_t cm1 = *_clockout | _clockbit;
|
|
|
|
// uint8_t cm0 = *_clockout & ~_clockbit;
|
|
|
|
|
|
|
|
// uint8_t oldSREG = SREG;
|
|
|
|
// cli();
|
|
|
|
// if (_bitorder == LSBFIRST)
|
|
|
|
// {
|
|
|
|
// for (uint8_t m = 0x01; m != 0x80; m <<= 1)
|
|
|
|
// {
|
|
|
|
// if (_value & m) *_dataout = dm1;
|
|
|
|
// else *_dataout = dm0;
|
|
|
|
// *_clockout = cm1;
|
|
|
|
// *_clockout = cm0;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// for (uint8_t m = 0x80; m > 0; m >>= 1)
|
|
|
|
// {
|
|
|
|
// if (_value & m) *_dataout = dm1;
|
|
|
|
// else *_dataout = dm0;
|
|
|
|
// *_clockout = cm1;
|
|
|
|
// *_clockout = cm0;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// SREG = oldSREG;
|
|
|
|
// return 1;
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
2013-08-29 05:39:24 -04:00
|
|
|
//
|
|
|
|
// reads back the last value written.
|
|
|
|
//
|
2013-08-28 16:30:00 -04:00
|
|
|
int FastShiftOut::read()
|
|
|
|
{
|
|
|
|
return _value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -- END OF FILE --
|