|
|
@@ -151,24 +151,42 @@ void _shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t valu |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static const unsigned maxSpeed = 10000000ULL; //10 MHz |
|
|
|
static const unsigned maxSpeedBeforeDelay = 392000000ULL; //max F_CPU_ACTUAL before doing delays (measured for 10MHz, -O2) |
|
|
|
|
|
|
|
void shiftOut_lsbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value) |
|
|
|
{ |
|
|
|
uint8_t mask; |
|
|
|
for (mask=0x01; mask; mask <<= 1) { |
|
|
|
digitalWrite(dataPin, value & mask); |
|
|
|
digitalWrite(clockPin, HIGH); |
|
|
|
digitalWrite(clockPin, LOW); |
|
|
|
} |
|
|
|
uint8_t mask; |
|
|
|
if (F_CPU_ACTUAL > maxSpeedBeforeDelay) { |
|
|
|
uint32_t cycles = (F_CPU_ACTUAL / 2 / maxSpeed); |
|
|
|
uint32_t t = ARM_DWT_CYCCNT; |
|
|
|
for (mask = 0x01; mask; mask <<= 1) { |
|
|
|
digitalWrite(dataPin, value & mask); |
|
|
|
do {;} while(ARM_DWT_CYCCNT - t < cycles); |
|
|
|
t += cycles / 2; |
|
|
|
|
|
|
|
digitalWrite(clockPin, HIGH); |
|
|
|
do {;} while(ARM_DWT_CYCCNT - t < cycles); |
|
|
|
t += cycles; |
|
|
|
|
|
|
|
digitalWrite(clockPin, LOW); |
|
|
|
do {;} while(ARM_DWT_CYCCNT - t < cycles); |
|
|
|
t += cycles / 2; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
for (mask=0x01; mask; mask <<= 1) { |
|
|
|
digitalWrite(dataPin, value & mask); |
|
|
|
digitalWrite(clockPin, HIGH); |
|
|
|
digitalWrite(clockPin, LOW); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void shiftOut_msbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value) |
|
|
|
{ |
|
|
|
uint8_t mask; |
|
|
|
for (mask=0x80; mask; mask >>= 1) { |
|
|
|
digitalWrite(dataPin, value & mask); |
|
|
|
digitalWrite(clockPin, HIGH); |
|
|
|
digitalWrite(clockPin, LOW); |
|
|
|
} |
|
|
|
uint32_t v; |
|
|
|
asm volatile ("rbit %0, %1" : "=r" (v) : "r" (value) ); |
|
|
|
shiftOut_lsbFirst(dataPin, clockPin, v >> 24); |
|
|
|
} |
|
|
|
|
|
|
|
uint8_t _shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) |