feat: restore 3-bit SPI encoding at 3.0 MHz with zero-gap transmission to align with FCOB-2.7 clock rate

This commit is contained in:
2026-07-08 12:03:32 +08:00
parent 88dbb8f069
commit 85b805963a

View File

@@ -128,33 +128,29 @@ void UI_ShowSosPage(void);
* WS2812B 幻彩 LED 单线驱动函数 (24MHz 1T 模式下精准时序控制)
* ========================================================================= */
void WS2812_EncodeByte5(u8 v, u8 *buf)
{
u8 p7 = (v & 0x80) ? 0x1C : 0x18;
u8 p6 = (v & 0x40) ? 0x1C : 0x18;
u8 p5 = (v & 0x20) ? 0x1C : 0x18;
u8 p4 = (v & 0x10) ? 0x1C : 0x18;
u8 p3 = (v & 0x08) ? 0x1C : 0x18;
u8 p2 = (v & 0x04) ? 0x1C : 0x18;
u8 p1 = (v & 0x02) ? 0x1C : 0x18;
u8 p0 = (v & 0x01) ? 0x1C : 0x18;
const u16 code SPI_LUT[16] = {
0x924, 0x926, 0x934, 0x936, 0x9A4, 0x9A6, 0x9B4, 0x9B6,
0xD24, 0xD26, 0xD34, 0xD36, 0xDA4, 0xDA6, 0xDB4, 0xDB6
};
buf[0] = (p7 << 3) | (p6 >> 2);
buf[1] = (p6 << 6) | (p5 << 1) | (p4 >> 4);
buf[2] = (p4 << 4) | (p3 >> 1);
buf[3] = (p3 << 7) | (p2 << 2) | (p1 >> 3);
buf[4] = (p1 << 5) | p0;
void WS2812_EncodeByte(u8 v, u8 *buf)
{
u16 p1 = SPI_LUT[v >> 4];
u16 p2 = SPI_LUT[v & 0x0F];
buf[0] = p1 >> 4;
buf[1] = ((p1 & 0x0F) << 4) | (p2 >> 8);
buf[2] = p2;
}
void WS2812_Write24Bit(u8 g, u8 r, u8 b)
{
u8 xdata buf[15];
u8 xdata buf[9];
u8 i;
u16 timeout;
WS2812_EncodeByte5(g, &buf[0]);
WS2812_EncodeByte5(r, &buf[5]);
WS2812_EncodeByte5(b, &buf[10]);
WS2812_EncodeByte(g, &buf[0]);
WS2812_EncodeByte(r, &buf[3]);
WS2812_EncodeByte(b, &buf[6]);
EA = 0;
@@ -162,31 +158,31 @@ void WS2812_Write24Bit(u8 g, u8 r, u8 b)
P2M1 &= ~((1 << 3) | (1 << 5));
P2M0 |= ((1 << 3) | (1 << 5));
SPCTL = 0xD0; // Enable SPI at SYSCLK/4 (6.0 MHz)
SPCTL = 0xD0; // Enable SPI at SYSCLK/4 (3.0 MHz actual clock on board)
SPSTAT = 0xC0; // Clear flags
SPDAT = buf[0]; // Goes to shift register immediately
// Wait about 20 system cycles (halfway through transmission) to avoid WCOL
// Wait about 20 system cycles to avoid WCOL
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
SPDAT = buf[1]; // Goes to transmit buffer
for (i = 2; i < 15; i++)
for (i = 2; i < 9; i++)
{
timeout = 2000;
while (!(SPSTAT & 0x80) && --timeout); // Wait with timeout
SPSTAT = 0xC0;
SPDAT = buf[i]; // Write buf[i] to transmit buffer
SPDAT = buf[i]; // Write buf[i] to transmit buffer (zero gap!)
}
timeout = 2000;
while (!(SPSTAT & 0x80) && --timeout); // Wait for buf[13]
while (!(SPSTAT & 0x80) && --timeout); // Wait for buf[7]
SPSTAT = 0xC0;
timeout = 2000;
while (!(SPSTAT & 0x80) && --timeout); // Wait for buf[14]
while (!(SPSTAT & 0x80) && --timeout); // Wait for buf[8]
SPSTAT = 0xC0;
SPCTL = 0x90; // Disable SPI
@@ -1058,7 +1054,7 @@ void main(void)
}
else if (cmd == 't' || cmd == 'T')
{
Uart_SendString("[UART SIM] SPI 6MHz Clock Test on P2.5 (SCLK) and P2.3 (MOSI) active. Press reset to exit.\r\n");
Uart_SendString("[UART SIM] SPI 3MHz Clock Test on P2.5 (SCLK) and P2.3 (MOSI) active. Press reset to exit.\r\n");
// Configure SCLK (P2.5) and MOSI (P2.3) as push-pull output
P2M1 &= ~((1 << 3) | (1 << 5));
P2M0 |= ((1 << 3) | (1 << 5));