forked from Makuna/NeoPixelBus
@@ -39,6 +39,7 @@ extern "C"
|
||||
void send_data_12mhz_400(uint8_t* data, size_t sizeData, volatile uint8_t* port, uint8_t pinMask);
|
||||
void send_data_16mhz_800(uint8_t* data, size_t sizeData, volatile uint8_t* port, uint8_t pinMask);
|
||||
void send_data_16mhz_400(uint8_t* data, size_t sizeData, volatile uint8_t* port, uint8_t pinMask);
|
||||
void send_data_32mhz(uint8_t* data, size_t sizeData, volatile uint8_t* port, uint8_t pinMask, const uint8_t cycleTiming);
|
||||
}
|
||||
|
||||
class NeoAvrSpeed800KbpsBase
|
||||
@@ -62,8 +63,10 @@ public:
|
||||
#endif // PORTD
|
||||
send_data_12mhz_800_PortB(data, sizeData, pinMask);
|
||||
|
||||
#elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000L) // 16Mhz CPU
|
||||
#elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000UL) // 16Mhz CPU
|
||||
send_data_16mhz_800(data, sizeData, port, pinMask);
|
||||
#elif (F_CPU >= 31000000UL) && (F_CPU <= 35000000UL) // 32Mhz CPU
|
||||
send_data_32mhz(data, sizeData, port, pinMask, 3);
|
||||
#else
|
||||
#error "CPU SPEED NOT SUPPORTED"
|
||||
#endif
|
||||
@@ -112,8 +115,10 @@ public:
|
||||
#elif (F_CPU >= 11100000UL) && (F_CPU <= 14300000UL) // 12Mhz CPU
|
||||
send_data_12mhz_400(data, sizeData, port, pinMask);
|
||||
|
||||
#elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000L) // 16Mhz CPU
|
||||
#elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000UL) // 16Mhz CPU
|
||||
send_data_16mhz_400(data, sizeData, port, pinMask);
|
||||
#elif (F_CPU >= 31000000UL) && (F_CPU <= 35000000UL) // 32Mhz CPU
|
||||
send_data_32mhz(data, sizeData, port, pinMask, 7);
|
||||
#else
|
||||
#error "CPU SPEED NOT SUPPORTED"
|
||||
#endif
|
||||
|
@@ -520,7 +520,7 @@ void send_data_12mhz_400(uint8_t* data, size_t sizeData, volatile uint8_t* port,
|
||||
[ptr] "e" (ptr));
|
||||
}
|
||||
|
||||
#elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000L) // 16Mhz CPU
|
||||
#elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000UL) // 16Mhz CPU
|
||||
|
||||
void send_data_16mhz_800(uint8_t* data, size_t sizeData, volatile uint8_t* port, uint8_t pinMask)
|
||||
{
|
||||
@@ -641,6 +641,75 @@ void send_data_16mhz_400(uint8_t* data, size_t sizeData, volatile uint8_t* port,
|
||||
[lo] "r" (lo));
|
||||
}
|
||||
|
||||
#elif (F_CPU >= 31000000UL) && (F_CPU <= 35000000UL) // 32Mhz CPU
|
||||
|
||||
void send_data_32mhz(uint8_t* data,
|
||||
size_t sizeData,
|
||||
volatile uint8_t* port,
|
||||
uint8_t pinMask,
|
||||
const uint8_t cycleTiming)
|
||||
{
|
||||
volatile uint16_t i = (uint16_t)sizeData; // Loop counter
|
||||
volatile uint8_t* ptr = data; // Pointer to next byte
|
||||
volatile uint8_t b = *ptr++; // Current byte value
|
||||
volatile uint8_t hi; // PORT w/output bit set high
|
||||
volatile uint8_t lo; // PORT w/output bit set low
|
||||
|
||||
volatile uint8_t next;
|
||||
volatile uint8_t bit;
|
||||
volatile uint8_t cycle;
|
||||
volatile uint8_t cycleCount;
|
||||
|
||||
hi = *port | pinMask;
|
||||
lo = *port & ~pinMask;
|
||||
next = lo;
|
||||
bit = 8;
|
||||
cycleCount = cycleTiming;
|
||||
|
||||
asm volatile(
|
||||
"head20:" "\n\t" // Clk Pseudocode
|
||||
"st %a[port], %[hi]" "\n\t" // 2 PORT = hi
|
||||
"sbrc %[byte], 7" "\n\t" // 1-2 if(b & 128)
|
||||
"mov %[next], %[hi]" "\n\t" // 0-1 next = hi
|
||||
"mov %[cycle], %[cycleCount]" "\n\t" // 0-1 cycle = shortCycle
|
||||
"cycleLoop1:" "\n\t"
|
||||
"dec %[cycle]" "\n\t" // 1 cycle--
|
||||
"brne cycleLoop1" "\n\t" // 2 if(cycle != 0) -> (cycleLoop1)
|
||||
"st %a[port], %[next]" "\n\t" // 2 PORT = next
|
||||
"mov %[cycle], %[cycleCount]" "\n\t" // 0-1 cycle = shortCycle
|
||||
"cycleLoop2:" "\n\t"
|
||||
"dec %[cycle]" "\n\t" // 1 cycle--
|
||||
"brne cycleLoop2" "\n\t" // 2 if(cycle != 0) -> (cycleLoop2)
|
||||
"rjmp .+0" "\n\t" // 2 nop nop (timing tuning)
|
||||
"st %a[port], %[lo]" "\n\t" // 2 PORT = lo
|
||||
"mov %[next] , %[lo]" "\n\t" // 1 next = lo
|
||||
"mov %[cycle], %[cycleCount]" "\n\t" // 0-1 cycle = shortCycle
|
||||
"cycleLoop3:" "\n\t"
|
||||
"dec %[cycle]" "\n\t" // 1 cycle--
|
||||
"brne cycleLoop3" "\n\t" // 2 if(cycle != 0) -> (cycleLoop3)
|
||||
"dec %[bit]" "\n\t" // 1 bit--
|
||||
"breq nextbyte20" "\n\t" // 1-2 if(bit == 0) (from dec above)
|
||||
"rol %[byte]" "\n\t" // 1 b <<= 1 (T = 15)
|
||||
"rjmp head20" "\n\t" // 2 -> head20 (next bit out)
|
||||
"nextbyte20:" "\n\t" // (T = 15)
|
||||
"ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 16)
|
||||
"ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 18)
|
||||
"sbiw %[count], 1" "\n\t" // 2 i-- (T = 38)
|
||||
"brne head20" "\n" // 2 if(i != 0) -> (next byte)
|
||||
// outputs
|
||||
: [port] "+e" (port),
|
||||
[byte] "+r" (b),
|
||||
[bit] "+r" (bit),
|
||||
[next] "+r" (next),
|
||||
[cycle] "+r" (cycle),
|
||||
[count] "+w" (i)
|
||||
// inputs
|
||||
: [ptr] "e" (ptr),
|
||||
[hi] "r" (hi),
|
||||
[lo] "r" (lo),
|
||||
[cycleCount] "r" (cycleCount));
|
||||
}
|
||||
|
||||
#else
|
||||
#error "CPU SPEED NOT SUPPORTED"
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user