/** * @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 *********************************/