feat: simplify double-buffered driver by using direct array indexing in data space to avoid compiler register allocation bugs
This commit is contained in:
31
App/main.c
31
App/main.c
@@ -145,7 +145,6 @@ void WS2812_EncodeByte(u8 v, u8 *buf)
|
|||||||
void WS2812_Write24Bit(u8 g, u8 r, u8 b)
|
void WS2812_Write24Bit(u8 g, u8 r, u8 b)
|
||||||
{
|
{
|
||||||
u8 data buf[10];
|
u8 data buf[10];
|
||||||
u8 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9;
|
|
||||||
u16 timeout;
|
u16 timeout;
|
||||||
|
|
||||||
buf[0] = 0x00; // Prepend dummy 0x00 to absorb SPI hardware startup delay/glitch
|
buf[0] = 0x00; // Prepend dummy 0x00 to absorb SPI hardware startup delay/glitch
|
||||||
@@ -153,10 +152,6 @@ void WS2812_Write24Bit(u8 g, u8 r, u8 b)
|
|||||||
WS2812_EncodeByte(r, &buf[4]);
|
WS2812_EncodeByte(r, &buf[4]);
|
||||||
WS2812_EncodeByte(b, &buf[7]);
|
WS2812_EncodeByte(b, &buf[7]);
|
||||||
|
|
||||||
b0 = buf[0]; b1 = buf[1]; b2 = buf[2]; b3 = buf[3];
|
|
||||||
b4 = buf[4]; b5 = buf[5]; b6 = buf[6]; b7 = buf[7];
|
|
||||||
b8 = buf[8]; b9 = buf[9];
|
|
||||||
|
|
||||||
EA = 0;
|
EA = 0;
|
||||||
|
|
||||||
// Ensure P2.3 (MOSI) and P2.5 (SCLK) are configured as push-pull output
|
// Ensure P2.3 (MOSI) and P2.5 (SCLK) are configured as push-pull output
|
||||||
@@ -166,27 +161,27 @@ void WS2812_Write24Bit(u8 g, u8 r, u8 b)
|
|||||||
SPSTAT = 0xC0; // Clear flags
|
SPSTAT = 0xC0; // Clear flags
|
||||||
SPCTL = 0xD0; // Enable SPI at SYSCLK/4 (3.0 MHz actual clock on board)
|
SPCTL = 0xD0; // Enable SPI at SYSCLK/4 (3.0 MHz actual clock on board)
|
||||||
|
|
||||||
SPDAT = b0; // Start transmitting dummy 0x00 (absorbs startup delay at MOSI=0)
|
SPDAT = buf[0]; // Start transmitting dummy 0x00 (absorbs startup delay at MOSI=0)
|
||||||
// Wait 30 NOPs to ensure b0 has moved to the shifter
|
// Wait 30 NOPs to ensure buf[0] has moved to the shifter
|
||||||
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
|
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
|
||||||
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
|
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
|
||||||
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
|
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
|
||||||
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
|
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
|
||||||
|
|
||||||
SPDAT = b1; // Buffer b1 (zero gap!)
|
SPDAT = buf[1]; // Buffer buf[1] (zero gap!)
|
||||||
|
|
||||||
// Transmission loop unrolled with double-buffering and timeout protection
|
// Transmission loop unrolled with double-buffering and timeout protection
|
||||||
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = b2;
|
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = buf[2];
|
||||||
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = b3;
|
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = buf[3];
|
||||||
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = b4;
|
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = buf[4];
|
||||||
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = b5;
|
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = buf[5];
|
||||||
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = b6;
|
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = buf[6];
|
||||||
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = b7;
|
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = buf[7];
|
||||||
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = b8;
|
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = buf[8];
|
||||||
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = b9;
|
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; SPDAT = buf[9];
|
||||||
|
|
||||||
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; // Wait for b8 to finish shifting, b9 moves to shifter
|
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; // Wait for buf[8] to finish shifting, buf[9] moves to shifter
|
||||||
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; // Wait for b9 to finish shifting
|
timeout = 2000; while (!(SPSTAT & 0x80) && --timeout); SPSTAT = 0xC0; // Wait for buf[9] to finish shifting
|
||||||
|
|
||||||
SPCTL = 0x90; // Disable SPI
|
SPCTL = 0x90; // Disable SPI
|
||||||
WS2812_DI = 0;
|
WS2812_DI = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user