WS2812_ATY.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /**
  2. * @file WS2812_ATY.c
  3. *
  4. * @param Project DEVICE_DRIVER_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2026 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief functions of WS2812 for C platform
  20. *
  21. * @version
  22. * - 1_01_251112 > ATY
  23. * -# Refactor to Dev-style; remove legacy global interfaces
  24. * - 1_02_251218 > ATY
  25. * -# Refactor all
  26. ********************************************************************************
  27. */
  28. #ifndef __WS2812_ATY_C
  29. #define __WS2812_ATY_C
  30. #include "WS2812_ATY.h"
  31. /******************************* For user *************************************/
  32. /******************************************************************************/
  33. /**
  34. * @brief Auto flush
  35. *
  36. * @param dev
  37. * @param buffer
  38. * @param count
  39. * @return uint8_t
  40. */
  41. uint8_t WS2812_AutoFlush(struct WS2812_ATY_Dev* dev, uint8_t* buffer, uint16_t count){
  42. uint8_t errCode = 0;
  43. __ATY_LOCK(dev);
  44. if(dev->autoUpdate != 0){
  45. errCode = dev->set(buffer, count);
  46. }
  47. __ATY_UNLOCK(dev);
  48. return errCode;
  49. }
  50. /**
  51. * @brief Flush buffer
  52. *
  53. * @param dev
  54. * @return uint8_t
  55. * @note if use SetPixel, disable dev->autoUpdate and flush light by hands
  56. */
  57. uint8_t WS2812_Flush(struct WS2812_ATY_Dev* dev){
  58. uint8_t errCode = 0;
  59. __ATY_LOCK(dev);
  60. errCode = dev->set(dev->buffer, dev->count);
  61. __ATY_UNLOCK(dev);
  62. return errCode;
  63. }
  64. /**
  65. * @brief Set RGB
  66. *
  67. * @param dev
  68. * @param index
  69. * @param R
  70. * @param G
  71. * @param B
  72. */
  73. uint8_t WS2812_SetRGB(struct WS2812_ATY_Dev* dev, uint16_t index, uint8_t R, uint8_t G, uint8_t B){
  74. __ATY_LOCK(dev);
  75. if(index < dev->count){
  76. uint8_t i = 0;
  77. uint8_t colors[3] = {G * dev->brightness, R * dev->brightness, B * dev->brightness};
  78. for(i = 0; i < 24; i++){
  79. if(colors[i / 8] & (1 << (7 - (i % 8)))){
  80. dev->buffer[index * 24 + i] = dev->code1;
  81. }
  82. else{
  83. dev->buffer[index * 24 + i] = dev->code0;
  84. }
  85. }
  86. }
  87. __ATY_UNLOCK(dev);
  88. return 0;
  89. }
  90. /**
  91. * @brief Get RGB
  92. *
  93. * @param dev
  94. * @param index
  95. * @param R
  96. * @param G
  97. * @param B
  98. */
  99. void WS2812_GetRGB(struct WS2812_ATY_Dev* dev, uint16_t index, uint8_t* R, uint8_t* G, uint8_t* B){
  100. if(index < dev->count){
  101. uint8_t i = 0;
  102. uint8_t colors[3] = {0};
  103. for(i = 0; i < 24; i++){
  104. if(dev->buffer[index * 24 + i] == dev->code1){
  105. colors[i / 8] |= (1 << (7 - (i % 8)));
  106. }
  107. *G = colors[0] / dev->brightness;
  108. *R = colors[1] / dev->brightness;
  109. *B = colors[2] / dev->brightness;
  110. }
  111. }
  112. }
  113. /**
  114. * @brief Fill
  115. *
  116. * @param dev
  117. * @param R
  118. * @param G
  119. * @param B
  120. * @return uint8_t
  121. */
  122. uint8_t WS2812_Fill(struct WS2812_ATY_Dev* dev, uint8_t R, uint8_t G, uint8_t B){
  123. for(uint16_t i = 0; i < dev->count; i++){
  124. WS2812_SetRGB(dev, i, R, G, B);
  125. }
  126. WS2812_AutoFlush(dev, dev->buffer, dev->count);
  127. return 0;
  128. }
  129. /**
  130. * @brief Set pixel
  131. *
  132. * @param dev
  133. * @param index
  134. * @param R
  135. * @param G
  136. * @param B
  137. * @return uint8_t
  138. */
  139. uint8_t WS2812_SetPixel(struct WS2812_ATY_Dev* dev, uint16_t index, uint8_t R, uint8_t G, uint8_t B){
  140. if(index < dev->count){
  141. WS2812_SetRGB(dev, index, R, G, B);
  142. }
  143. WS2812_AutoFlush(dev, dev->buffer, dev->count);
  144. return 0;
  145. }
  146. /**
  147. * @brief Get pixel
  148. *
  149. * @param dev
  150. * @param index
  151. * @param R
  152. * @param G
  153. * @param B
  154. * @return uint8_t
  155. */
  156. uint8_t WS2812_GetPixel(struct WS2812_ATY_Dev* dev, uint16_t index, uint8_t* R, uint8_t* G, uint8_t* B){
  157. if(index < dev->count){
  158. WS2812_GetRGB(dev, index, R, G, B);
  159. }
  160. return 0;
  161. }
  162. /**
  163. * @brief Clear
  164. *
  165. * @param dev
  166. * @return uint8_t
  167. */
  168. uint8_t WS2812_Clear(struct WS2812_ATY_Dev* dev){
  169. for(uint16_t i = 0; i < dev->count; ++i){
  170. WS2812_SetRGB(dev, i, 0, 0, 0);
  171. }
  172. WS2812_AutoFlush(dev, dev->buffer, dev->count);
  173. return 0;
  174. }
  175. #endif /* __WS2812_ATY_C */
  176. /************************************ etc *************************************/
  177. /* init
  178. // WS2812 ----------------------------------------------------------------------
  179. #include "WS2812_ATY.h"
  180. #define WS2812_1_COUNT 8
  181. uint8_t WS2812_1_Buffer[WS2812_1_COUNT * 24 + 1] = {0};
  182. uint8_t WS2812_1_Set(uint8_t* buffer, uint8_t count){
  183. return HAL_SPI_Transmit_DMA(&hspi1, buffer, count * 24 + 1);
  184. }
  185. struct WS2812_ATY_Dev WS2812_ATY_Dev_1 = {
  186. .set = WS2812_1_Set,
  187. .count = WS2812_1_COUNT,
  188. .buffer = WS2812_1_Buffer,
  189. .brightness = 0.1,
  190. .code0 = 0XE0,
  191. .code1 = 0XF8,
  192. .autoUpdate = 1,
  193. .lock = __ATY_UNLOCKED
  194. };
  195. */
  196. /* use
  197. uint8_t WS2812_index = 0;
  198. void WS2812_Test(void){
  199. WS2812_index++;
  200. if(WS2812_index > 8) WS2812_index = 0;
  201. if(WS2812_index == 0)
  202. WS2812_Fill(&WS2812_ATY_Dev_1, 0xFF, 0x00, 0x00);
  203. else if(WS2812_index == 1)
  204. WS2812_Fill(&WS2812_ATY_Dev_1, 0x00, 0xFF, 0x00);
  205. else if(WS2812_index == 2)
  206. WS2812_Fill(&WS2812_ATY_Dev_1, 0x00, 0x00, 0xFF);
  207. else if(WS2812_index == 3)
  208. WS2812_Fill(&WS2812_ATY_Dev_1, 0xFF, 0xFF, 0x00);
  209. else if(WS2812_index == 4)
  210. WS2812_Fill(&WS2812_ATY_Dev_1, 0xFF, 0x00, 0xFF);
  211. else if(WS2812_index == 5)
  212. WS2812_Fill(&WS2812_ATY_Dev_1, 0x00, 0xFF, 0xFF);
  213. else if(WS2812_index == 6)
  214. WS2812_Fill(&WS2812_ATY_Dev_1, 0xFF, 0xFF, 0xFF);
  215. else if(WS2812_index == 7)
  216. WS2812_Fill(&WS2812_ATY_Dev_1, 0x00, 0x00, 0x00);
  217. else if(WS2812_index == 8){
  218. WS2812_SetPixel(&WS2812_ATY_Dev_1, 0, 0xFF, 0x00, 0x00);
  219. WS2812_SetPixel(&WS2812_ATY_Dev_1, 1, 0x00, 0xFF, 0x00);
  220. WS2812_SetPixel(&WS2812_ATY_Dev_1, 2, 0x00, 0x00, 0xFF);
  221. WS2812_SetPixel(&WS2812_ATY_Dev_1, 3, 0x00, 0x00, 0x00);
  222. WS2812_SetPixel(&WS2812_ATY_Dev_1, 4, 0xFF, 0xFF, 0x00);
  223. WS2812_SetPixel(&WS2812_ATY_Dev_1, 5, 0xFF, 0x00, 0xFF);
  224. WS2812_SetPixel(&WS2812_ATY_Dev_1, 6, 0x00, 0xFF, 0xFF);
  225. WS2812_SetPixel(&WS2812_ATY_Dev_1, 7, 0xFF, 0xFF, 0xFF);
  226. }
  227. WS2812_Flush(&WS2812_ATY_Dev_1);
  228. // WS2812_Clear(&WS2812_ATY_Dev_1);
  229. // WS2812_Fill(&WS2812_ATY_Dev_1, 0xFF, 0x00, 0x00);
  230. }
  231. */
  232. /******************************************************************************/
  233. /******************************** End Of File *********************************/