/**
* @file WS2812_ATY.c
*
* @param Project DEVICE_DRIVER_ATY_LIB
*
* @author ATY
*
* @copyright
* - Copyright 2017 - 2026 MZ-ATY
* - This code follows:
* - MZ-ATY Various Contents Joint Statement -
*
* https://mengze.top/MZ-ATY_VCJS
* - CC 4.0 BY-NC-SA -
*
* https://creativecommons.org/licenses/by-nc-sa/4.0/
* - Your use will be deemed to have accepted the terms of this statement.
*
* @brief functions of WS2812 for C platform
*
* @version
* - 1_01_251112 > ATY
* -# Refactor to Dev-style; remove legacy global interfaces
* - 1_02_251218 > ATY
* -# Refactor all
********************************************************************************
*/
#ifndef __WS2812_ATY_C
#define __WS2812_ATY_C
#include "WS2812_ATY.h"
/******************************* For user *************************************/
/******************************************************************************/
/**
* @brief Auto flush
*
* @param dev
* @param buffer
* @param count
* @return uint8_t
*/
uint8_t WS2812_AutoFlush(struct WS2812_ATY_Dev* dev, uint8_t* buffer, uint16_t count){
uint8_t errCode = 0;
__ATY_LOCK(dev);
if(dev->autoUpdate != 0){
errCode = dev->set(buffer, count);
}
__ATY_UNLOCK(dev);
return errCode;
}
/**
* @brief Flush buffer
*
* @param dev
* @return uint8_t
* @note if use SetPixel, disable dev->autoUpdate and flush light by hands
*/
uint8_t WS2812_Flush(struct WS2812_ATY_Dev* dev){
uint8_t errCode = 0;
__ATY_LOCK(dev);
errCode = dev->set(dev->buffer, dev->count);
__ATY_UNLOCK(dev);
return errCode;
}
/**
* @brief Set RGB
*
* @param dev
* @param index
* @param R
* @param G
* @param B
*/
uint8_t WS2812_SetRGB(struct WS2812_ATY_Dev* dev, uint16_t index, uint8_t R, uint8_t G, uint8_t B){
__ATY_LOCK(dev);
if(index < dev->count){
uint8_t i = 0;
uint8_t colors[3] = {G * dev->brightness, R * dev->brightness, B * dev->brightness};
for(i = 0; i < 24; i++){
if(colors[i / 8] & (1 << (7 - (i % 8)))){
dev->buffer[index * 24 + i] = dev->code1;
}
else{
dev->buffer[index * 24 + i] = dev->code0;
}
}
}
__ATY_UNLOCK(dev);
return 0;
}
/**
* @brief Get RGB
*
* @param dev
* @param index
* @param R
* @param G
* @param B
*/
void WS2812_GetRGB(struct WS2812_ATY_Dev* dev, uint16_t index, uint8_t* R, uint8_t* G, uint8_t* B){
if(index < dev->count){
uint8_t i = 0;
uint8_t colors[3] = {0};
for(i = 0; i < 24; i++){
if(dev->buffer[index * 24 + i] == dev->code1){
colors[i / 8] |= (1 << (7 - (i % 8)));
}
*G = colors[0] / dev->brightness;
*R = colors[1] / dev->brightness;
*B = colors[2] / dev->brightness;
}
}
}
/**
* @brief Fill
*
* @param dev
* @param R
* @param G
* @param B
* @return uint8_t
*/
uint8_t WS2812_Fill(struct WS2812_ATY_Dev* dev, uint8_t R, uint8_t G, uint8_t B){
for(uint16_t i = 0; i < dev->count; i++){
WS2812_SetRGB(dev, i, R, G, B);
}
WS2812_AutoFlush(dev, dev->buffer, dev->count);
return 0;
}
/**
* @brief Set pixel
*
* @param dev
* @param index
* @param R
* @param G
* @param B
* @return uint8_t
*/
uint8_t WS2812_SetPixel(struct WS2812_ATY_Dev* dev, uint16_t index, uint8_t R, uint8_t G, uint8_t B){
if(index < dev->count){
WS2812_SetRGB(dev, index, R, G, B);
}
WS2812_AutoFlush(dev, dev->buffer, dev->count);
return 0;
}
/**
* @brief Get pixel
*
* @param dev
* @param index
* @param R
* @param G
* @param B
* @return uint8_t
*/
uint8_t WS2812_GetPixel(struct WS2812_ATY_Dev* dev, uint16_t index, uint8_t* R, uint8_t* G, uint8_t* B){
if(index < dev->count){
WS2812_GetRGB(dev, index, R, G, B);
}
return 0;
}
/**
* @brief Clear
*
* @param dev
* @return uint8_t
*/
uint8_t WS2812_Clear(struct WS2812_ATY_Dev* dev){
for(uint16_t i = 0; i < dev->count; ++i){
WS2812_SetRGB(dev, i, 0, 0, 0);
}
WS2812_AutoFlush(dev, dev->buffer, dev->count);
return 0;
}
#endif /* __WS2812_ATY_C */
/************************************ etc *************************************/
/* init
// WS2812 ----------------------------------------------------------------------
#include "WS2812_ATY.h"
#define WS2812_1_COUNT 8
uint8_t WS2812_1_Buffer[WS2812_1_COUNT * 24 + 1] = {0};
uint8_t WS2812_1_Set(uint8_t* buffer, uint8_t count){
return HAL_SPI_Transmit_DMA(&hspi1, buffer, count * 24 + 1);
}
struct WS2812_ATY_Dev WS2812_ATY_Dev_1 = {
.set = WS2812_1_Set,
.count = WS2812_1_COUNT,
.buffer = WS2812_1_Buffer,
.brightness = 0.1,
.code0 = 0XE0,
.code1 = 0XF8,
.autoUpdate = 1,
.lock = __ATY_UNLOCKED
};
*/
/* use
uint8_t WS2812_index = 0;
void WS2812_Test(void){
WS2812_index++;
if(WS2812_index > 8) WS2812_index = 0;
if(WS2812_index == 0)
WS2812_Fill(&WS2812_ATY_Dev_1, 0xFF, 0x00, 0x00);
else if(WS2812_index == 1)
WS2812_Fill(&WS2812_ATY_Dev_1, 0x00, 0xFF, 0x00);
else if(WS2812_index == 2)
WS2812_Fill(&WS2812_ATY_Dev_1, 0x00, 0x00, 0xFF);
else if(WS2812_index == 3)
WS2812_Fill(&WS2812_ATY_Dev_1, 0xFF, 0xFF, 0x00);
else if(WS2812_index == 4)
WS2812_Fill(&WS2812_ATY_Dev_1, 0xFF, 0x00, 0xFF);
else if(WS2812_index == 5)
WS2812_Fill(&WS2812_ATY_Dev_1, 0x00, 0xFF, 0xFF);
else if(WS2812_index == 6)
WS2812_Fill(&WS2812_ATY_Dev_1, 0xFF, 0xFF, 0xFF);
else if(WS2812_index == 7)
WS2812_Fill(&WS2812_ATY_Dev_1, 0x00, 0x00, 0x00);
else if(WS2812_index == 8){
WS2812_SetPixel(&WS2812_ATY_Dev_1, 0, 0xFF, 0x00, 0x00);
WS2812_SetPixel(&WS2812_ATY_Dev_1, 1, 0x00, 0xFF, 0x00);
WS2812_SetPixel(&WS2812_ATY_Dev_1, 2, 0x00, 0x00, 0xFF);
WS2812_SetPixel(&WS2812_ATY_Dev_1, 3, 0x00, 0x00, 0x00);
WS2812_SetPixel(&WS2812_ATY_Dev_1, 4, 0xFF, 0xFF, 0x00);
WS2812_SetPixel(&WS2812_ATY_Dev_1, 5, 0xFF, 0x00, 0xFF);
WS2812_SetPixel(&WS2812_ATY_Dev_1, 6, 0x00, 0xFF, 0xFF);
WS2812_SetPixel(&WS2812_ATY_Dev_1, 7, 0xFF, 0xFF, 0xFF);
}
WS2812_Flush(&WS2812_ATY_Dev_1);
// WS2812_Clear(&WS2812_ATY_Dev_1);
// WS2812_Fill(&WS2812_ATY_Dev_1, 0xFF, 0x00, 0x00);
}
*/
/******************************************************************************/
/******************************** End Of File *********************************/