From e0d7f6e84a0923ee885bcba8117397e08b922818 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Thu, 2 Feb 2023 13:00:59 -0800 Subject: [PATCH] Lgt8f328p (#633) * 32Mhz 800Kbps * 32Mhz 400Kbps * Tuned and Tested --- src/internal/NeoAvrMethod.h | 9 +++-- src/internal/NeoPixelAvr.c | 71 ++++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/internal/NeoAvrMethod.h b/src/internal/NeoAvrMethod.h index c58249e..8dc0e9b 100644 --- a/src/internal/NeoAvrMethod.h +++ b/src/internal/NeoAvrMethod.h @@ -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 diff --git a/src/internal/NeoPixelAvr.c b/src/internal/NeoPixelAvr.c index 84e9893..bf602b9 100644 --- a/src/internal/NeoPixelAvr.c +++ b/src/internal/NeoPixelAvr.c @@ -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