#include "rgb.h"
#include "spi.h"

// 定义 0 和 1 的波形特征码（根据你的 SPI 频率可能需要微调）
#define TIM_ZERO          0xC0  
#define TIM_ONE           0xF8

// 缓存数组：1个起始0 + PIXEL_NUM*24位数据 + 1个停止0
uint8_t RGB_BYTE_Buffer[PIXEL_NUM * 24 + 2] = {0};

/**
  * @brief  RGB驱动初始化 (HAL库下，CubeMX已完成大部分初始化)
  */
void RGB_Init(void)
{
    // 在 CubeMX 中已经生成了 MX_SPI3_Init()，这里可以留空或做逻辑初始化
    for(int i=0; i < sizeof(RGB_BYTE_Buffer); i++) RGB_BYTE_Buffer[i] = 0;
}

/**
  * @brief  将数据发送到硬件（DMA方式）
  */
void RGB_Update(void)
{
    // 使用 HAL 库的 DMA 发送函数
    // 参数：句柄，数据地址，数据长度
    HAL_SPI_Transmit_DMA(&hspi3, RGB_BYTE_Buffer, PIXEL_NUM * 24 + 2);
    
    // 原代码中使用 while 等待标志位，在 HAL 中如果需要同步等待可以使用：
    // while (HAL_SPI_GetState(&hspi3) != HAL_SPI_STATE_READY);
}

/**
  * @brief  全灯设置同一个颜色
  */
void RGB_SetFullColor(uint8_t r, uint8_t g, uint8_t b)
{
    uint16_t i, j;

    RGB_BYTE_Buffer[0] = 0;                               
    RGB_BYTE_Buffer[PIXEL_NUM * 24 + 1] = 0;    

    // 填充第一个灯珠的数据 (WS2812 顺序通常是 G-R-B)
    for(j = 0; j < 8; j++)
    {
        RGB_BYTE_Buffer[j + 1]      = ((g << j) & 0x80) ? TIM_ONE : TIM_ZERO;
        RGB_BYTE_Buffer[j + 1 + 8]  = ((r << j) & 0x80) ? TIM_ONE : TIM_ZERO;
        RGB_BYTE_Buffer[j + 1 + 16] = ((b << j) & 0x80) ? TIM_ONE : TIM_ZERO;            
    }

    // 复制到其他灯珠
    for(i = 1; i < PIXEL_NUM; i++)
    {
        for(j = 1; j < 25; j++)
        {
            RGB_BYTE_Buffer[(24 * i) + j] = RGB_BYTE_Buffer[j];  
        }        
    } 

    RGB_Update();
}

/**
  * @brief  设置每个灯珠不同的颜色
  */
void RGB_SetPixelColor(uint8_t pixel[PIXEL_NUM][3])
{
    uint8_t i, j;
    
    RGB_BYTE_Buffer[0] = 0;                               
    RGB_BYTE_Buffer[PIXEL_NUM * 24 + 1] = 0;    
    
    for(i = 0; i < PIXEL_NUM; i++)
    {    
        for(j = 0; j < 8; j++)
        {
            // pixel[i][0]=R, [i][1]=G, [i][2]=B
            RGB_BYTE_Buffer[(i * 24) + j + 1]      = ((pixel[i][1] << j) & 0x80) ? TIM_ONE : TIM_ZERO;
            RGB_BYTE_Buffer[(i * 24) + j + 1 + 8]  = ((pixel[i][0] << j) & 0x80) ? TIM_ONE : TIM_ZERO;
            RGB_BYTE_Buffer[(i * 24) + j + 1 + 16] = ((pixel[i][2] << j) & 0x80) ? TIM_ONE : TIM_ZERO;    
        }    
    }
    
    RGB_Update();
}
